<template>
  <div class="side-bar-wrapper" :style="SideBarWrapperStyle">
    <div class="side-bar-item">
      <div class="model">
        <div class="header">
          <div class="header-left">
            <span class="ml-8">模型</span>
          </div>
        </div>
        <div class="part1">
          <SideItemList
            :list="sideList"
            @click="handleSideListClick"
          ></SideItemList>
          <div class="part1-right">
            <div class="model-content" v-show="sideListName === '几何'">
              <div class="header-detail">
                <div>名称</div>
                <div>
                  <img src="../assets/line.svg" alt="" />
                  <span class="id-element">ID</span>
                  <img src="../assets/line.svg" alt="" />
                  <div class="color-box">
                    <img src="../assets/little_color_picker.svg" />
                  </div>
                </div>
              </div>
              <Scroll :height="modelContentHeight" use-y-bar>
                <div class="geometry">
                  <div class="header">
                    <img src="../assets/down_triangle.svg" alt="" />
                    <img src="../assets/model_group_icon.svg" alt="" />
                    <img src="../assets/mesh_group_icon.svg" alt="" />
                    <span>几何</span>
                  </div>
                  <Tree
                    :data="geometryCompile()"
                    :show-line="true"
                    :show-icon="true"
                    link-line="solid"
                    virtual
                    style="padding-left: 20px; box-sizing: border-box"
                    use-y-bar
                    class="row-font"
                    checkbox
                    v-if="batchMode"
                    ref="tree"
                  >
                    <!-- 多选模式 -->
                    <template #label="{ data }">
                      <div
                        @contextmenu.prevent="modelItemMenu($event, data)"
                        style="width: 100%"
                        @click="treeItemClick(data)"
                      >
                        <div class="geo-label">
                          <div class="flex-c-c">
                            <img
                              src="../assets/model_icon.svg"
                              alt=""
                              @click="showOrHidePartId(data)"
                              v-show="data.show"
                            />
                            <img
                              src="../assets/model_icon_hide.svg"
                              alt=""
                              @click="showOrHidePartId(data)"
                              v-show="!data.show"
                            />
                            <img src="../assets/mesh_icon.svg" alt="" />
                            <!-- <Icon :icon="Cubes" class="mr-10"></Icon> -->
                            <span class="part-name">{{ data.label }} </span>
                          </div>
                          <div class="flex-c-r">
                            <span class="id-element">{{ data.id }}</span>
                            <div
                              class="color-box"
                              :style="`background-color: ${getGeoItemColor(
                                data
                              )};
                          width: 16px;
                          height: 16px;
                          margin-right: 7px;
                        `"
                            ></div>
                          </div>
                        </div>
                      </div>
                    </template>
                  </Tree>
                  <Tree
                    :data="geometryCompile()"
                    :show-line="true"
                    :show-icon="true"
                    link-line="solid"
                    virtual
                    style="padding-left: 20px; box-sizing: border-box"
                    use-y-bar
                    class="row-font"
                    v-if="!batchMode"
                  >
                    <!-- 单选模式 -->
                    <template #label="{ data }">
                      <div
                        @contextmenu.prevent="modelItemMenu($event, data)"
                        style="width: 100%"
                      >
                        <div class="geo-label">
                          <div class="flex-c-c">
                            <img
                              src="../assets/model_icon.svg"
                              alt=""
                              @click="showOrHidePartId(data)"
                              v-show="data.show"
                            />
                            <img
                              src="../assets/model_icon_hide.svg"
                              alt=""
                              @click="showOrHidePartId(data)"
                              v-show="!data.show"
                            />
                            <img src="../assets/mesh_icon.svg" alt="" />
                            <!-- <Icon :icon="Cubes" class="mr-10"></Icon> -->
                            <span class="part-name">{{ data.label }} </span>
                          </div>
                          <div class="flex-c-r">
                            <span class="id-element">{{ data.id }}</span>
                            <div
                              class="color-box"
                              :style="`background-color: ${getGeoItemColor(
                                data
                              )};
                          width: 16px;
                          height: 16px;
                          margin-right: 7px;
                        `"
                            ></div>
                          </div>
                        </div>
                      </div>
                    </template>
                  </Tree>
                </div>
                <div class="mesh">
                  <div class="header">
                    <img src="../assets/down_triangle.svg" alt="" />
                    <img src="../assets/mesh_group.svg" alt="" />
                    <span>网格</span>
                  </div>
                  <div class="content">
                    <div
                      class="row row-font"
                      v-for="item in coreStore.elements"
                      :key="item.name"
                    >
                      <div class="left">
                        <img src="../assets/mesh_control.svg" alt="" />
                        <span>{{ item.name }} ({{ item.num }})</span>
                      </div>
                    </div>
                  </div>
                </div>
                <div class="assembly">
                  <div class="header" @contextmenu.prevent="setMenu">
                    <img src="../assets/down_triangle.svg" alt="" />
                    <img src="../assets/assembly_group.svg" alt="" />
                    <span>集合</span>
                  </div>
                  <div class="content" v-if="showSet">
                    <!-- TODO: 这里有多处需要修改。 -->
                    <div
                      class="row row-font"
                      v-for="(item, index) in sets"
                      v-bind:key="index"
                      v-bind:class="item.is_selected ? 'selected' : ''"
                      @click="set_click(item)"
                      @contextmenu.prevent="setItemMenu($event, item, index)"
                    >
                      <div class="left">
                        <img src="../assets/property.svg" alt="" />
                        <!-- <Icon :icon="Cubes" class="mr-10"></Icon> -->
                        <span>{{ item.name }}</span>
                      </div>
                      <div class="right">
                        <span class="id-element">{{ item.id }}</span>
                        <div class="color-box"></div>
                      </div>
                    </div>
                  </div>
                </div>
              </Scroll>
            </div>
            <div class="model-content" v-show="sideListName === '材料'">
              <div class="header-detail">
                <div>名称</div>
                <div>
                  <img src="../assets/line.svg" alt="" />
                  <span class="id-element">ID</span>
                  <img src="../assets/line.svg" alt="" />
                  <div class="color-box">
                    <img src="../assets/little_color_picker.svg" />
                  </div>
                </div>
              </div>
              <Scroll :height="modelContentHeight" use-y-bar>
                <div class="material">
                  <div class="header" @contextmenu.prevent="materialMenu">
                    <img src="../assets/down_triangle.svg" alt="" />
                    <img
                      src="../assets/material_group.svg"
                      alt=""
                      style="width: 16px; height: 16px"
                    />
                    <span>材料</span>
                  </div>

                  <div class="content" v-if="showMaterial">
                    <div
                      class="row row-font"
                      v-for="(item, index) in materials"
                      v-bind:key="index"
                      v-bind:class="item.is_selected ? 'selected' : ''"
                      @click="material_click(item)"
                      @contextmenu.prevent="
                        materialItemMenu($event, item, index)
                      "
                    >
                      <div class="left">
                        <img src="../assets/material.svg" alt="" />
                        <!-- <Icon :icon="Cubes" class="mr-10"></Icon> -->
                        <span>{{ item.name }}</span>
                      </div>
                      <div class="right">
                        <span class="id-element">{{ item.id }}</span>
                        <div class="color-box"></div>
                      </div>
                    </div>
                  </div>
                </div>
              </Scroll>
            </div>
            <div class="model-content" v-show="sideListName === '属性'">
              <div class="header-detail">
                <div>名称</div>
                <div>
                  <img src="../assets/line.svg" alt="" />
                  <span class="id-element">ID</span>
                  <img src="../assets/line.svg" alt="" />
                  <div class="color-box">
                    <img src="../assets/little_color_picker.svg" />
                  </div>
                </div>
              </div>
              <Scroll :height="modelContentHeight" use-y-bar>
                <div class="property">
                  <div class="header" @contextmenu.prevent="propertyMenu">
                    <img src="../assets/down_triangle.svg" alt="" />
                    <img src="../assets/property_group.svg" alt="" />
                    <span>属性</span>
                  </div>
                  <div class="content" v-if="showProperty">
                    <div
                      class="row row-font"
                      v-for="(item, index) in properties"
                      v-bind:key="index"
                      v-bind:class="item.is_selected ? 'selected' : ''"
                      @click="property_click(item)"
                      @contextmenu.prevent="
                        propertyItemMenu($event, item, index)
                      "
                    >
                      <div class="left">
                        <img src="../assets/property.svg" alt="" />
                        <!-- <Icon :icon="Cubes" class="mr-10"></Icon> -->
                        <span>{{ item.name }}</span>
                      </div>
                      <div class="right">
                        <span class="id-element">{{ item.id }}</span>
                        <div class="color-box"></div>
                      </div>
                    </div>
                  </div>
                </div>
              </Scroll>
            </div>
            <div class="model-content" v-show="sideListName === '载荷/约束'">
              <div class="header-detail">
                <div>名称</div>
                <div>
                  <img src="../assets/line.svg" alt="" />
                  <span class="id-element">ID</span>
                  <img src="../assets/line.svg" alt="" />
                  <div class="color-box">
                    <img src="../assets/little_color_picker.svg" />
                  </div>
                </div>
              </div>
              <Scroll :height="modelContentHeight" use-y-bar>
                <div class="material">
                  <div class="header" @contextmenu.prevent="loadConstraintMenu">
                    <img src="../assets/down_triangle.svg" alt="" />
                    <img
                      src="../assets/material_group.svg"
                      alt=""
                      style="width: 16px; height: 16px"
                    />
                    <span>载荷/约束</span>
                  </div>

                  <div class="content" v-if="showLoadConstraints">
                    <div
                      v-for="(item, index) in loadConstraints"
                      :key="index"
                      @click="load_constraints_click(item)"
                    >
                      <div
                        class="row row-font"
                        @contextmenu.prevent="
                          loadConstraintsItemMenu($event, item)
                        "
                      >
                        <div class="left">
                          <img src="../assets/material.svg" alt="" />
                          <!-- <Icon :icon="Cubes" class="mr-10"></Icon> -->
                          <span>{{ item.name }}</span>
                        </div>
                        <div class="right">
                          <span class="id-element">{{ item.id }}</span>
                          <div class="color-box"></div>
                        </div>
                      </div>
                      <div v-if="item.forceInfo">
                        <div
                          v-for="(force, i) in item.forceInfo"
                          :key="i"
                          @click="force_info_click(force, item)"
                          class="row row-font"
                          @contextmenu.prevent="
                            loadInfoItemMenu($event, force, item)
                          "
                        >
                          <div class="left" style="padding-left: 16px">
                            <img src="../assets/material.svg" alt="" />
                            <!-- <Icon :icon="Cubes" class="mr-10"></Icon> -->
                            <span>{{ force.name }}</span>
                          </div>
                          <div class="right">
                            <span class="id-element">{{ force.id }}</span>
                            <div class="color-box"></div>
                          </div>
                        </div>
                      </div>
                      <div v-else-if="item.displacementInfo">
                        <div
                          v-for="(displacement, i) in item.displacementInfo"
                          :key="i"
                          @click="force_info_click(displacement, item)"
                          class="row row-font"
                          @contextmenu.prevent="
                            loadInfoItemMenu($event, displacement, item)
                          "
                        >
                          <div class="left" style="padding-left: 16px">
                            <img src="../assets/material.svg" alt="" />
                            <!-- <Icon :icon="Cubes" class="mr-10"></Icon> -->
                            <span>{{ displacement.name }}</span>
                          </div>
                          <div class="right">
                            <span class="id-element">{{
                              displacement.id
                            }}</span>
                            <div class="color-box"></div>
                          </div>
                        </div>
                      </div>
                    </div>
                    <div
                      v-for="(item, index) in temperatures"
                      :key="index"
                      @click="temperatures_click(item)"
                    >
                      <div
                        class="row row-font"
                        @contextmenu.prevent="
                          temperatureItemMenu($event, item, index)
                        "
                      >
                        <div class="left">
                          <img src="../assets/material.svg" alt="" />
                          <!-- <Icon :icon="Cubes" class="mr-10"></Icon> -->
                          <span>{{ item.name }}</span>
                        </div>
                        <div class="right">
                          <span class="id-element">{{ item.id }}</span>
                          <div class="color-box"></div>
                        </div>
                      </div>
                    </div>
                  </div>
                </div>
              </Scroll>
            </div>
            <div class="model-content" v-show="sideListName === '坐标系'">
              <div class="header-detail">
                <div>名称</div>
                <div>
                  <img src="../assets/line.svg" alt="" />
                  <span class="id-element">ID</span>
                  <img src="../assets/line.svg" alt="" />
                  <div class="color-box">
                    <img src="../assets/little_color_picker.svg" />
                  </div>
                </div>
              </div>
              <Scroll :height="modelContentHeight" use-y-bar>
                <div class="material">
                  <div class="header">
                    <img src="../assets/down_triangle.svg" alt="" />
                    <img
                      src="../assets/material_group.svg"
                      alt=""
                      style="width: 16px; height: 16px"
                    />
                    <span>坐标系</span>
                  </div>
                  <div class="content" v-if="showLoadCoordinates">
                    <div
                      v-for="(item, index) in loadCoordinates"
                      :key="index"
                      style="padding-top: 10px"
                    >
                      <div
                        class="row row-font"
                        @contextmenu.prevent="
                          loadCoordinatesItemMenu($event, item)
                        "
                      >
                        <div class="left">
                          <img src="../assets/material.svg" alt="" />
                          <!-- <Icon :icon="Cubes" class="mr-10"></Icon> -->
                          <span>{{ item.label }}</span>
                        </div>
                      </div>
                      <div v-if="item.label === '坐标系'">
                        <div
                          class="row row-font"
                          v-for="(coordinate, id) in coordinates.coordinates"
                          :key="id"
                          :class="coordinate.is_selected ? 'selected' : ''"
                          @click="coordinate_click(coordinate)"
                          @contextmenu.prevent="
                            CoordinateItemMenu($event, coordinate, id)
                          "
                        >
                          <div class="left" style="padding-left: 16px">
                            <img src="../assets/material.svg" alt="" />
                            <span>{{ coordinate.name }}</span>
                          </div>
                          <div class="right">
                            <span class="id-element">{{ coordinate.id }}</span>
                          </div>
                        </div>
                      </div>
                      <div v-if="item.label === '节点坐标系'">
                        <div
                          class="row row-font"
                          v-for="(
                            nodeCoordinate, id
                          ) in nodeCoordinates.nodeCoordinates"
                          :key="id"
                          :class="nodeCoordinate.is_selected ? 'selected' : ''"
                          @click="nodeCoordinate_click(nodeCoordinate)"
                          @contextmenu.prevent="
                            NodeCoordinateItemMenu($event, nodeCoordinate, id)
                          "
                        >
                          <div class="left" style="padding-left: 16px">
                            <img src="../assets/material.svg" alt="" />
                            <span>{{ nodeCoordinate.name }}</span>
                          </div>
                          <div class="right">
                            <span class="id-element">{{
                              nodeCoordinate.id
                            }}</span>
                          </div>
                        </div>
                      </div>
                      <div v-if="item.label === '材料方向'">
                        <div
                          class="row row-font"
                          v-for="(
                            materialOrientation, id
                          ) in materialOrientations.materialOrientations"
                          :key="id"
                          :class="
                            materialOrientation.is_selected ? 'selected' : ''
                          "
                          @click="
                            materialOrientation_click(materialOrientation)
                          "
                          @contextmenu.prevent="
                            MaterialOrientationItemMenu(
                              $event,
                              materialOrientation,
                              id
                            )
                          "
                        >
                          <div class="left" style="padding-left: 16px">
                            <img src="../assets/material.svg" alt="" />
                            <span>{{ materialOrientation.name }}</span>
                          </div>
                          <div class="right">
                            <span class="id-element">{{
                              materialOrientation.id
                            }}</span>
                          </div>
                        </div>
                      </div>
                    </div>
                  </div>
                </div>
              </Scroll>
            </div>
            <div class="solver-task-list" v-show="sideListName === '求解任务'">
              <SolverTaskList></SolverTaskList>
            </div>
            <div class="model-content" v-show="sideListName === '输出'">
              <div class="header-detail">
                <div>名称</div>
                <div>
                  <img src="../assets/line.svg" alt="" />
                  <span class="id-element">ID</span>
                  <img src="../assets/line.svg" alt="" />
                  <div class="color-box">
                    <img src="../assets/little_color_picker.svg" />
                  </div>
                </div>
              </div>
              <Scroll :height="modelContentHeight" use-y-bar>
                <div class="outputblock">
                  <div class="header" @contextmenu.prevent="outputblockMenu">
                    <img src="../assets/down_triangle.svg" alt="" />
                    <img src="../assets/property_group.svg" alt="" />
                    <span>输出块</span>
                  </div>
                  <div class="content" v-if="showOutputblock">
                    <div
                      class="row row-font"
                      v-for="(item, index) in outputblocks"
                      v-bind:key="index"
                      v-bind:class="item.is_selected ? 'selected' : ''"
                      @click="outputblock_click(item)"
                      @contextmenu.prevent="
                        outputblockItemMenu($event, item, index)
                      "
                    >
                      <div class="left">
                        <img src="../assets/property.svg" alt="" />
                        <!-- <Icon :icon="Cubes" class="mr-10"></Icon> -->
                        <span>{{ item.name }}</span>
                      </div>
                      <div class="right">
                        <span class="id-element">{{ item.id }}</span>
                        <div class="color-box"></div>
                      </div>
                    </div>
                  </div>
                </div>
                <div class="card">
                  <div class="header" @contextmenu.prevent="cardMenu">
                    <img src="../assets/down_triangle.svg" alt="" />
                    <img src="../assets/property_group.svg" alt="" />
                    <span>卡片</span>
                  </div>
                  <div class="content" v-if="showCard">
                    <div
                      class="row row-font"
                      v-for="(item, index) in cards"
                      v-bind:key="index"
                      v-bind:class="item.is_selected ? 'selected' : ''"
                      @click="card_click(item)"
                      @contextmenu.prevent="cardItemMenu($event, item, index)"
                    >
                      <div class="left">
                        <img src="../assets/property.svg" alt="" />
                        <!-- <Icon :icon="Cubes" class="mr-10"></Icon> -->
                        <span>{{ item.name }}</span>
                      </div>
                      <div class="right">
                        <span class="id-element">{{ item.id }}</span>
                        <div class="color-box"></div>
                      </div>
                    </div>
                  </div>
                </div>
              </Scroll>
              <!-- <SolverTaskList></SolverTaskList> -->
            </div>
            <div class="model-content" v-show="sideListName === '场'">
              <div class="header-detail">
                <div>名称</div>
                <div>
                  <img src="../assets/line.svg" alt="" />
                  <span class="id-element">ID</span>
                  <img src="../assets/line.svg" alt="" />
                  <div class="color-box">
                    <img src="../assets/little_color_picker.svg" />
                  </div>
                </div>
              </div>
              <Scroll :height="modelContentHeight" use-y-bar>
                <div class="field">
                  <div class="header" @contextmenu.prevent="fieldMenu">
                    <img src="../assets/down_triangle.svg" alt="" />
                    <img
                      src="../assets/material_group.svg"
                      alt=""
                      style="width: 16px; height: 16px"
                    />
                    <span>场</span>
                  </div>

                  <div class="content" v-if="showField">
                    <div
                      class="row row-font"
                      v-for="(item, index) in fields"
                      v-bind:key="index"
                      v-bind:class="item.is_selected ? 'selected' : ''"
                      @click="field_click(item)"
                      @contextmenu.prevent="fieldItemMenu($event, item, index)"
                    >
                      <div class="left">
                        <img src="../assets/material.svg" alt="" />
                        <!-- <Icon :icon="Cubes" class="mr-10"></Icon> -->
                        <span>{{ item.name }}</span>
                      </div>
                      <div class="right">
                        <span class="id-element">{{ item.id }}</span>
                        <div class="color-box"></div>
                      </div>
                    </div>
                  </div>
                </div>
              </Scroll>
            </div>
          </div>
        </div>
        <div class="model-editor">
          <div class="model-editor-header">
            <div class="header-left">
              <span class="ml-8">卡片编辑器</span>
            </div>
          </div>
          <div :style="DataCardEditorAutoHeight" v-if="showMaterialEditor">
            <DataCardEditor
              :material-in="selectedMaterial"
              :editorProps="editorProps"
              :propsInitial="propsInitial"
              :material-list="materials"
              @update="handleUpdate"
              @onclick="handleInsideClick"
            ></DataCardEditor>
          </div>
          <div v-if="showSolverEditor">
            <div class="header-detail">
              <div>对象</div>
              <img src="../assets/line.svg" alt="" />
              <div>值</div>
            </div>
            <Scroll :height="solverEditorHeight" use-y-bar>
              <div>
                <div class="prop-row">
                  <div>名称</div>
                  <div>求解任务1</div>
                </div>
                <div class="prop-row">
                  <div>ID</div>
                  <div>394</div>
                </div>
                <div class="prop-row">
                  <div>颜色</div>
                  <div>
                    <div class="color-label"></div>
                  </div>
                </div>
                <div class="prop-row">
                  <div>输入文件</div>
                  <div class="text_overflow_single">
                    OSS://test-xiamu/some-test/datasets/文件夹A/test
                  </div>
                </div>
                <div class="prop-row">
                  <div>输出地址</div>
                  <div class="text_overflow_single">
                    OSS://test-xiamu/some-test/datasets/文件夹A/test
                  </div>
                </div>
                <div class="prop-row">
                  <div>求解器</div>
                  <div>SGFEM</div>
                </div>
                <div class="prop-row">
                  <div>CPU</div>
                  <div>2000</div>
                </div>
                <div class="prop-row">
                  <div>内存 (Gi)</div>
                  <div>4</div>
                </div>
                <div class="prop-row">
                  <div>运行状态</div>
                  <div>正在运行</div>
                </div>
              </div>
            </Scroll>
          </div>
          <div v-if="!showMaterialEditor && !showSolverEditor">
            <div class="header-detail">
              <div>对象</div>
              <img src="../assets/line.svg" alt="" />
              <div>值</div>
            </div>
            <div>
              <div class="prop-row">
                <div>模型名称</div>
                <div>模型A</div>
              </div>
              <div class="prop-row">
                <div>ID</div>
                <div>2847</div>
              </div>
              <div class="prop-row">
                <div>颜色</div>
                <div>
                  <div class="color-label"></div>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
  <MaterialSelectModal @emitMaterial="handleChildMat"></MaterialSelectModal>
  <LayerEditorModal></LayerEditorModal>
</template>
<script setup lang="ts">
import MaterialSelectModal from "./Material/MaterialSelectModal.vue";
import LayerEditorModal from "./Property/LayerEditorModal.vue";
import SideItemList from "@/UI/components/SideItemList.vue";
import { nextTick, reactive, ref } from "vue";
import { Contextmenu, Message, Scroll, Tree } from "cax-ui";
import { storeToRefs } from "pinia";
import { useCoreStore, _global, useRuleStore } from "@/UI/store";

import DataCardEditor from "./DataCardEditor/DataCardEditor.vue";
import {
  CARD_TYPE_initial,
  cardEditorProps,
  Displacement_TYPE_initial,
  displacementEditorProps,
  EditorProps,
  Force_TYPE_initial,
  forceEditorProps,
  initialCoordinates,
  initialDisplacement,
  initialForce,
  initialLoadConstraint,
  initialMaterialMAT1,
  initialPropertyPSHELL,
  initialNodesSet,
  initialElementsSet,
  initialComponentsSet,
  initialSetsSet,
  initialField,
  Load_Constraint_TYPE_initial,
  Load_Coordinates_TYPE_initial,
  loadConstraintEditorProps,
  loadCoordinatesEditorProps,
  nodeCoordinatesEditorProps,
  fieldEditorProps,
  MATERIAL_TYPE_initial,
  materialEditorProps,
  OUTPUTBLOCK_TYPE_initial,
  outputEditorProps,
  parseCard,
  parseDisplacement,
  parseForce,
  parseLoadConstraints,
  parseLoadCoordinates,
  parseMaterial,
  parseOutputblock,
  parseProperty,
  parseSet,
  parseTemperature,
  parseField,
  FIELD_TYPE_initial,
  PROPERTY_TYPE_initial,
  propertyEditorProps,
  PropsInitial,
  SelectMaterial,
  setEditorProps,
  initialTemperature,
  temperatureEditorProps,
  TEMPERATURE_TYPE_initial,
  initialNodeCoordinates,
  NODECOORDINATES_TYPE_initial,
  parseNodeCoordinates,
  initialMaterialOrientations,
  materialOrientationsEditorProps,
  MATERIALORIENTATIONS_TYPE_initial,
  parseMaterialOrientations,
  SETS_TYPE_initial,
} from "./sidebar/constants";
import {
  color2rgb255arr,
  rgb255str2rgb1arr,
  str_or_rgb1arr2gyColor,
} from "./sidebar/color";
import {
  EntityPropRecorder,
  GeoItem,
  getEntityIds,
  getGeoItemById,
  getGeoItemColor,
  parseBomInfo,
  TREE_ROOT,
} from "./sidebar/model";
import { getPropById, PropertyItem } from "./sidebar/property";
import { TemperatureItem } from "./sidebar/temperature";
import { MaterialItem } from "./sidebar/material";
import {
  displacementItem,
  ForceItem,
  LoadConstraintsItem,
} from "./sidebar/loadConstraints";
import {
  SelectedNode,
  SelectedCoordinate,
  vectorLength,
  dotProduct,
  crossProduct,
  normalize,
  subtract,
  NoteTcell,
  NodeCoordinates,
  setOffset,
  MaterialOrientationsItem,
  CoordinateItem,
} from "./sidebar/coordinates";
import { SetItem } from "./sidebar/set";
import { FieldItem } from "./sidebar/field";
import { TArrow, TCell } from "cax-base";
type Vector3 = [number, number, number];
import SolverTaskList from "@/UI/components/SideItemComp/SolverTaskList.vue";
import { STATUS_CODE } from "@/FrontProcessing";
import { IO } from "stl-typescript";

export interface SideBarProps {
  geometry: any;
}

const sideList = ref([
  {
    id: 1,
    name: "几何",
    isActive: true,
  },
  {
    id: 2,
    name: "材料",
    isActive: false,
  },
  {
    id: 3,
    name: "属性",
    isActive: false,
  },
  {
    id: 4,
    name: "坐标系",
    isActive: false,
  },
  {
    id: 5,
    name: "载荷/约束",
    isActive: false,
  },
  {
    id: 6,
    name: "求解任务",
    isActive: false,
  },
  {
    id: 7,
    name: "输出",
    isActive: false,
  },
  {
    id: 8,
    name: "场",
    isActive: false,
  },
]);
const sideListName = ref("几何");

const modelContentHeight = (window.document.body.clientHeight - 48 - 8) * 0.5;
const solverEditorHeight =
  window.document.body.clientHeight * 0.38 - 48 - 34 - 20;
const SideBarWrapperStyle = {
  height: document.body.clientHeight - 48 - 8 + "px",
};
const DataCardEditorAutoHeight = {
  height: (window.document.body.clientHeight - 48 - 8) * 0.33 - 48 + "px",
  overflow: "auto",
};

// 针对模型树的多选情况
const tree = ref<InstanceType<typeof Tree>>();
const batchMode = ref(false);

function treeItemClick(data: GeoItem) {
  console.log("tree value:", tree.value?.getCheckedNodeData());
}

const coreStore = useCoreStore();
const ruleStore = useRuleStore();

const { bomInfo } = storeToRefs(coreStore);
const entityPropRecorder: EntityPropRecorder = new EntityPropRecorder();

IO.on("UpdateAllCards", () => {
  refreshMaterialList();
  refreshPropertyList();
  refreshCoordinateList();
  refreshSetList();
});

// 当检测到data中的数据变化时（例如prop_item.selected = false），这个函数会被立即触发，
// 更新数据后，data.propItem会被清除。但是如果对data.propItem进行赋值操作时，这个函数不会被触发。
function geometryCompile() {
  if (!bomInfo.value.name) return [];
  const data: GeoItem[] = parseBomInfo(
    entityPropRecorder,
    bomInfo.value,
    TREE_ROOT,
    false
  );
  console.log("data:", data);
  return data;
}

// 打开模型树中模型组件相关的菜单
async function modelItemMenu(event: MouseEvent, data: GeoItem) {
  // 根据属性卡片，创建二级菜单。
  let propChildren: { key: number; label: string }[] = [];
  properties.forEach((prop: PropertyItem) => {
    let propChild = {
      key: prop.id,
      label: prop.name,
    };
    propChildren.push(propChild);
  });
  // 未选择是则返回 null
  const selectedKeys = await Contextmenu.open({
    clientX: event.clientX,
    clientY: event.clientY,
    appear: true,
    configs: [
      {
        key: "assign_prop",
        label: "设置属性卡片",
        children: propChildren,
      },
      {
        key: "open_batch_mode",
        label: "打开多选模式",
      },
      {
        key: "close_batch_mode",
        label: "关闭多选模式",
      },
      {
        key: "delete",
        label: "删除",
      },
    ],
  });
  if (selectedKeys) {
    console.log("selectedKeys", selectedKeys);
    if (selectedKeys[0] == "open_batch_mode") {
      batchMode.value = true;
      // 打开多选模式
      return;
    }
    if (selectedKeys[0] == "close_batch_mode") {
      batchMode.value = false;
      // 关闭多选模式
      return;
    }
    if (selectedKeys[0] == "assign_prop") {
      alert("请先创建属性卡片！");
      return;
    }
    if (selectedKeys[0] === "设置属性卡片") {
      if (selectedKeys.length < 2) {
        alert("请先创建属性卡片！");
        return;
      }
      let prop_id = selectedKeys[1];
      if (typeof prop_id == "string") {
        prop_id = parseInt(prop_id);
      }
      let entity_ids: number[] = [];
      let geo_items: GeoItem[] = [];
      if (!batchMode.value) {
        // 单选模式
        entity_ids = getEntityIds(data);
      } else {
        // 多选模式
        const checkedData = tree.value?.getCheckedNodeData();
        if (checkedData?.length == 0) {
          alert("多选模式下，请先选中任意元素！");
          return;
        }
        checkedData?.forEach((item) => {
          console.log("item:", item);
          let id = parseInt(item.id);
          if (!isNaN(id)) {
            entity_ids.push(id);
            geo_items.push(item);
          }
        });
      }
      console.log("entity_ids:", entity_ids);
      _global.Engine.property
        .asssignProperty(entity_ids, prop_id)
        .then((res: any) => {
          console.log("set prop res:", res);
          console.log("entity_ids:", entity_ids);
          if (res.prop_ids?.length <= 0) {
            return;
          }
          // TODO: 返回值是正常的，但是设置颜色上出现问题了。
          // 难道批量赋值材料（针对父元素部分）也出问题了吗？
          for (let i = 0; i < entity_ids.length; i++) {
            let geoItem = null;
            if (batchMode.value) {
              geoItem = geo_items[i];
            } else {
              geoItem = getGeoItemById(data, entity_ids[i]); // 这一步找不到父组件的geoItem，需要进行修改。
            }
            const prop: any = getPropById(properties, res.prop_ids[i]);
            if (prop != null) {
              entityPropRecorder.record(entity_ids[i], prop);
              // set entity color
              if (prop.value) {
                console.log(
                  "set entity id ",
                  entity_ids[i],
                  ", color ",
                  prop.value.color
                );
                _global.Engine.color.set_entity_color(
                  entity_ids[i],
                  color2rgb255arr(prop.value.color)
                );
              }
            }
            if (prop != null && geoItem != null) {
              geoItem.prop = prop;
            }
          }
        });
    }
    if (selectedKeys[0] == "delete") {
      let entity_ids = getEntityIds(data);
      let geoItem: GeoItem | null = getGeoItemById(data, entity_ids[0]);
      if (geoItem == null) {
        alert("不支持删除!");
        return;
      } else {
        let dp_id: number =
          typeof geoItem.id === "string" ? parseInt(geoItem.id) : geoItem.id;
        _global.Engine.check.deleteD2(dp_id).then((res) => {
          coreStore.setBomInfo(res.bomInfo);
        });
      }
      return;
    }
  }
}

// 在模型树中，单击显示或者隐藏一个或者一组对象
// bug：不要建立id到GeoItem的map，map中的元素可能是数据的浅拷贝，这样当更新map中的数据时，页面中的数据可能不会被更新。
function showOrHidePartId(data: GeoItem) {
  data.show = !data.show;
  // 对父元素进行处理
  if (data.children.length == 0) {
    const dataId = parseInt(data.id);
    if (isNaN(dataId)) return;
    if (data.show) {
      _global.Engine.model.unmask(dataId);
    } else {
      _global.Engine.model.mask(dataId);
    }
    return;
  }

  const children = [...data.children];
  while (children.length > 0) {
    const item = children.pop();
    if (!item) continue;
    item.show = data.show;
    children.push(...item.children);
    if (item.children.length > 0) continue;
    const itemId = parseInt(item.id);
    if (isNaN(itemId)) continue;
    if (data.show) {
      _global.Engine.model.unmask(itemId);
    } else {
      _global.Engine.model.mask(itemId);
    }
  }
}

function handleChildMat(value: any) {
  // const id = parseInt(selectedValues["id"]);
  const selectedValues = selectedMaterial.value;
  //@ts-ignore
  const id = parseInt(selectedValues["id"]);
  let values = { ...value };
  selectedValues["id"] = values["id"];
  values["id"] = selectedValues["id"];
  values["name"] = selectedValues["name"];
  values["poissonsRatio"] = values["poissonRatio"];
  // console.log("parseValue1", value);
  values = parseMaterial(values);

  // TODO: 向后端插入该材料
  _global.Engine.material.modifyMaterial(id, values).then((res: any) => {
    console.log("update res:", res);
    materials.forEach((material_item) => {
      if (material_item.id == id) {
        material_item.value = parseMaterial(res["material"]);
        selectedMaterial.value = material_item.value;
        console.log("selectedMaterial.value", selectedMaterial.value);
      }
    });
    refreshItemEditor();
  });
  // insert_mat_record(value);
}

const materials: any[] = [];
const loadConstraints: LoadConstraintsItem[] = reactive<LoadConstraintsItem[]>(
  []
);

const loadCoordinates = ref([
  {
    label: "坐标系",
  },
  {
    label: "节点坐标系",
  },
  {
    label: "材料方向",
  },
]);

// 连接后台时访问一次数据
coreStore.Notify.subscribe(({ event }) => {
  if (event === "engine_ready") {
    _global.Engine.hooks.onConnected(() => {
      update_sets();
    });
  }
});

// 取消选中所有侧边栏中的item
function unselectAllItems() {
  unselectMaterials();
  unselectProperties();
  unselectSets();
}

function unselectMaterials() {
  materials.forEach((item) => {
    item.is_selected = false;
  });
}
// 创建material
function create_material() {
  let values = {};
  selectedMaterial.value = { ...initialMaterialMAT1 };
  editorProps.value = { ...materialEditorProps };
  propsInitial.value = { ...MATERIAL_TYPE_initial };
  refreshMaterialList();
  refreshItemEditor();
  insert_mat_record(values);
}

// 向后端插入材料记录
function insert_mat_record(values: any) {
  _global.Engine.material
    .createMaterial(values)
    .then((res: any) => {
      const m = res.material;
      unselectAllItems();
      console.log("insert res:", m);
      const material = {
        name: m["name"],
        id: m["id"],
        is_selected: true,
        value: parseMaterial(m),
      };

      // selectedMaterial中不能有任何值为undefined属性。
      selectedMaterial.value = material.value; // 这一步出错了

      materials.push(material);
      refreshMaterialList();
      refreshItemEditor();
    })
    .catch((errorMsg) => {
      alert(errorMsg);
    });
}
// 注册回调函数，访问后端得到材料卡片数据，并塞进material中
function rename_materials() {
  const prefix = ruleStore.materialNamePrefix;
  const suffix = ruleStore.materialNameSuffix;
  if (!prefix && !suffix) return;
  _global.Engine.material
    .batchRenameMaterials(prefix, suffix, materials)
    .then((materials_ins: any) => {
      console.log("materials_ins", materials_ins);
      materials_ins = materials_ins.result;
      // materials.length = 0;
      for (let material_ins of materials_ins) {
        const new_value = parseMaterial(material_ins);
        materials.forEach((material) => {
          if (material.id == material_ins.id) {
            material.name = material_ins.name;
            material.value = new_value;
          }
        });
      }
      refreshMaterialList();
    });
}

const showMaterial = ref(true);
const showLoadConstraints = ref(true);
const showLoadCoordinates = ref(true);
const showMaterialEditor = ref(false);
const showSolverEditor = ref(false);
const showProperty = ref(false);
const showCoordinate = ref(true);
const showLoadNodeCoordinates = ref(true);
const showField = ref(true);

const sets: any[] = [];
async function setMenu(event: MouseEvent) {
  // 未选择是则返回 null
  const selectedKeys = await Contextmenu.open({
    clientX: event.clientX,
    clientY: event.clientY,
    appear: true,
    configs: [
      { key: "create_set", label: "创建集合卡片" },
      { key: "get_all_sets", label: "刷新集合列表" },
    ],
  });

  if (selectedKeys && selectedKeys[0] == "create_set") {
    create_set();
  } else if (selectedKeys && selectedKeys[0] == "get_all_sets") {
    update_sets();
  }
}

function create_set() {
  selectedMaterial.value = { ...initialElementsSet };
  _global.Engine.set
    .createSet({
      values: "",
    })
    .then((res: any) => {
      const p = res.set;
      console.log("res", p);
      initialElementsSet.name = p["name"];
      initialElementsSet.id = p["id"];
      selectedMaterial.value = { ...initialElementsSet };
      editorProps.value = { ...setEditorProps };
      propsInitial.value = { ...SETS_TYPE_initial };
      let parseResult = parseSet(p);
      const set = {
        name: p["name"],
        id: p["id"],
        is_selected: true,
        value: parseResult,
      };
      // console.log("set", set);
      sets.push(set);
      // console.log(sets);
      refreshSetList();
      refreshItemEditor();
    });
}

function set_click(item: SetItem) {
  unselectAllItems();
  item.is_selected = true;
  selectedMaterial.value = item.value;
  editorProps.value = { ...setEditorProps };
  refreshMaterialList();
  refreshItemEditor();
}

async function setItemMenu(event: MouseEvent, item: SetItem, index: number) {
  // 未选择是则返回 null
  const selectedKeys = await Contextmenu.open({
    clientX: event.clientX,
    clientY: event.clientY,
    appear: true,
    configs: [{ key: "delete_set", label: "删除集合卡片" }],
  });

  if (selectedKeys && selectedKeys[0] == "delete_set") {
    // 删除set
    _global.Engine.set.deleteSet(item.id).then((res: string) => {
      sets.splice(index, 1);
      refreshSetList();
      if (item.is_selected) {
        item.is_selected = false;
        showDefaultItemEditor();
      }
    });
  }
}

// TODO: 把Set的记录加上去就可以了。
const showSet = ref(true);
// 刷新集合列表
function refreshSetList() {
  showSet.value = false;
  nextTick(() => {
    showSet.value = true;
  });
}

// TODO: update之后，还有删除、查询和修改等操作需要增加。
// 其实Set相关的接口还挺多的，估计要3-4个工作日才能做得完。
function update_sets() {
  _global.Engine.set.getAllSets().then((sets_ins: any) => {
    sets_ins = sets_ins.sets;
    sets.length = 0;
    for (let set of sets_ins) {
      const m = {
        name: "材料B",
        id: 958,
        is_selected: false,
        value: parseSet(set),
      };
      m.name = set["name"];
      m.id = set["id"];
      sets.push(m);
    }
    refreshSetList();
  });
}

let selectedMaterial = ref<SelectMaterial>({ ...initialMaterialMAT1 });
let editorProps = ref<EditorProps>({ ...materialEditorProps });
let propsInitial = ref<PropsInitial>({ ...MATERIAL_TYPE_initial });
async function materialMenu(event: MouseEvent) {
  // 未选择是则返回 null
  const selectedKeys = await Contextmenu.open({
    clientX: event.clientX,
    clientY: event.clientY,
    appear: true,
    configs: [
      { key: "create_material", label: "创建材料卡片" },
      { key: "batch_rename_materials", label: "批量重命名" },
    ],
  });

  if (selectedKeys && selectedKeys[0] == "create_material") {
    create_material();
  } else if (selectedKeys && selectedKeys[0] == "batch_rename_materials") {
    rename_materials();
  }
}
async function loadCoordinatesItemMenu(event: MouseEvent, item: any) {
  let configs: any[] = [];
  if (item.label === "坐标系") {
    configs = [
      { key: "coordinate_system", label: "坐标系" },
      { key: "coordinate_system_rename", label: "批量重命名" },
    ];
  } else if (item.label === "节点坐标系") {
    configs = [
      { key: "node_cs", label: "指定节点坐标系" },
      { key: "node_rename", label: "批量重命名" },
    ];
  } else if (item.label === "材料方向") {
    configs = [
      { key: "elem_cs", label: "指定材料方向" },
      { key: "elem_rename", label: "批量重命名" },
    ];
  }
  const selectedKeys = await Contextmenu.open({
    clientX: event.clientX,
    clientY: event.clientY,
    appear: true,
    configs,
  });
  // if(selectedKeys){
  //   create_force_set(selectedKeys[0].toString());
  // }
  if (selectedKeys && selectedKeys[0] === "coordinate_system") {
    create_coordinate_system();
  } else if (selectedKeys && selectedKeys[0] === "node_cs") {
    create_nodeCoordinates();
  } else if (selectedKeys && selectedKeys[0] === "elem_cs") {
    create_materialOrientations();
  }
}

const coordinates = reactive({
  coordinates: [] as CoordinateItem[],
});
function create_coordinate_system() {
  // selectedMaterial.value = { ...initialCoordinates };
  let values = {};
  _global.Engine.coordinate
    .createCoordinate(values)
    .then((res: any) => {
      const p = res;
      console.log(p);
      unselectAllItems();
      let parseResult = parseLoadCoordinates(p);
      const coordinate = {
        name: p["name"],
        id: p["id"],
        is_selected: true,
        value: parseResult,
        xAxis: null,
        yAxis: null,
        zAxis: null,
      };
      selectedMaterial.value = coordinate.value;
      editorProps.value = { ...loadCoordinatesEditorProps };
      propsInitial.value = { ...Load_Coordinates_TYPE_initial };
      coordinates.coordinates.push(coordinate);
      console.log("coordinates", coordinates);
      refreshCoordinateList();
      refreshItemEditor();
    })
    .catch((errorMsg) => {
      alert(errorMsg);
    });
  refreshLoadCoordinatesList();
  refreshItemEditor();
}
function refreshCoordinateList() {
  showCoordinate.value = false;
  nextTick(() => {
    showCoordinate.value = true;
  });
}
async function loadConstraintMenu(event: MouseEvent) {
  const selectedKeys = await Contextmenu.open({
    clientX: event.clientX,
    clientY: event.clientY,
    appear: true,
    configs: [
      { key: "ForceSet", label: "Force Set" },
      { key: "DisplacementSet", label: "Displacement Set" },
      { key: "MomentSet", label: "Moment Set" },
      { key: "PressureSet", label: "Pressure Set" },
      { key: "TemperatureSet", label: "Temperature Set" },
    ],
  });
  // if(selectedKeys){
  //   create_force_set(selectedKeys[0].toString());
  // }
  if (selectedKeys && selectedKeys[0] === "ForceSet") {
    create_force_set(selectedKeys[0].toString());
  } else if (selectedKeys && selectedKeys[0] === "DisplacementSet") {
    create_bcs();
  } else if (selectedKeys && selectedKeys[0] === "TemperatureSet") {
    create_temperature_set();
  }
}
async function loadConstraintsItemMenu(event: MouseEvent, item: any) {
  let configs: any[] = [];
  if (item.type === "force_set") {
    configs = [
      { key: "force_set", label: "集中力" },
      { key: "force_template1", label: "集中力模板1" },
      { key: "force_template2", label: "集中力模板2" },
      { key: "delete_force_set", label: "删除" },
    ];
  } else if (item.type === "displacement_set") {
    configs = [
      { key: "displacement", label: "位移" },
      { key: "displacement_template1", label: "位移模板1" },
      { key: "displacement_template2", label: "位移模板2" },
      { key: "delete_displacement", label: "删除" },
    ];
  }
  // 未选择是则返回 null
  const selectedKeys = await Contextmenu.open({
    clientX: event.clientX,
    clientY: event.clientY,
    appear: true,
    configs,
  });
  if (selectedKeys) {
    if (selectedKeys[0] == "force_set") {
      create_force(item["id"]);
    } else if (selectedKeys[0] == "delete_force_set") {
      delete_force_set(item);
    } else if (selectedKeys[0] == "displacement") {
      create_displacement(item["id"]);
    } else if (selectedKeys[0] == "delete_displacement") {
      delete_displacement_set(item);
    } else if (selectedKeys[0] == "force_template1") {
      create_force_template(item["id"], "template1");
    } else if (selectedKeys[0] == "force_template2") {
      create_force_template(item["id"], "template2");
    } else if (selectedKeys[0] == "displacement_template1") {
      create_displacement_template(item["id"], "template1");
    } else if (selectedKeys[0] == "displacement_template2") {
      create_displacement_template(item["id"], "template2");
    }
  }
}
async function loadInfoItemMenu(
  event: MouseEvent,
  force: ForceItem,
  item: LoadConstraintsItem
) {
  // console.log("item", item);
  // let configs: any[] = [];
  // if (item.type === "force_set") {
  //   configs = [
  //     { key: "delete_force", label: "删除" },
  //     { key: "clone_force", label: "克隆" },
  //   ];
  // }
  // 未选择是则返回 null
  const selectedKeys = await Contextmenu.open({
    clientX: event.clientX,
    clientY: event.clientY,
    appear: true,
    configs: [
      { key: "delete", label: "删除" },
      { key: "clone", label: "克隆" },
    ],
  });
  if (selectedKeys) {
    if (selectedKeys[0] === "delete") {
      deleteItem(force, item);
    } else if (selectedKeys[0] == "clone") {
      clone(force);
    }
  }
}
function deleteItem(force: ForceItem, item: LoadConstraintsItem) {
  if (item.type === "force_set") {
    _global.Engine.loadConstraints
      .deleteItem({
        name: force.name,
      })
      .then((res: any) => {
        if (item.forceInfo) {
          const w = item.forceInfo.find((a) => a.name === force.name);
          if (w?.normal) {
            _global.Engine.model.remove(w.normal);
          }
          item.forceInfo.splice(
            item.forceInfo.findIndex((a) => a.name === force.name),
            1
          );
        }
        showMaterialEditor.value = false;
      });
  } else if (item.type === "displacement_set") {
    _global.Engine.loadConstraints
      .deleteItem({
        type: item.type,
        name: force.name,
      })
      .then((res: any) => {
        if (item.displacementInfo) {
          const w = item.displacementInfo.find((a) => a.name === force.name);
          if (w?.normal.dof1) {
            _global.Engine.model.remove(w.normal.dof1);
          }
          if (w?.normal.dof2) {
            _global.Engine.model.remove(w.normal.dof2);
          }
          if (w?.normal.dof3) {
            _global.Engine.model.remove(w.normal.dof3);
          }
          if (w?.normal.dof4) {
            _global.Engine.model.remove(w.normal.dof4);
          }
          if (w?.normal.dof5) {
            _global.Engine.model.remove(w.normal.dof5);
          }
          if (w?.normal.dof6) {
            _global.Engine.model.remove(w.normal.dof6);
          }
          item.displacementInfo.splice(
            item.displacementInfo.findIndex((a) => a.name === force.name),
            1
          );
        }
        showMaterialEditor.value = false;
      });
  }
}
function clone(item: any) {
  console.log(
    "_global.Engine.selectBoxComp.selectedPoints",
    _global.Engine.selectBoxComp.selectedPoints
  );
}
function delete_displacement_set(item: any) {
  const param = {
    name: "",
    children: [],
  };
  if (loadConstraints.length !== 0) {
    loadConstraints.forEach((w: any, i: number) => {
      if (w.id === item.id && w.type === "displacement_set") {
        param.name = w.name;
        if (w.displacementInfo.length !== 0) {
          param.children = w.displacementInfo.map((e: any) => e.name);
          w.displacementInfo.forEach((q: displacementItem) => {
            if (q.normal.dof1) {
              _global.Engine.model.remove(q.normal.dof1);
            }
            if (q.normal.dof2) {
              _global.Engine.model.remove(q.normal.dof2);
            }
            if (q.normal.dof3) {
              _global.Engine.model.remove(q.normal.dof3);
            }
            if (q.normal.dof4) {
              _global.Engine.model.remove(q.normal.dof4);
            }
            if (q.normal.dof5) {
              _global.Engine.model.remove(q.normal.dof5);
            }
            if (q.normal.dof6) {
              _global.Engine.model.remove(q.normal.dof6);
            }
          });
        }
        _global.Engine.loadConstraints
          .deleteForceSet(param)
          .then((res: any) => {
            loadConstraints.splice(i, 1);
            showMaterialEditor.value = false;
          });
      }
    });
  }
  refreshLoadConstraintsList();
  refreshItemEditor();
}
function delete_force_set(item: any) {
  const param = {
    name: "",
    children: [],
  };
  if (loadConstraints.length !== 0) {
    loadConstraints.forEach((w: any, i: number) => {
      if (w.id === item.id && w.type === "force_set") {
        param.name = w.name;
        if (w.forceInfo.length !== 0) {
          param.children = w.forceInfo.map((e: any) => e.name);
          w.forceInfo.forEach((q: ForceItem) => {
            if (q.normal) {
              _global.Engine.model.remove(q.normal);
            }
          });
        }
        _global.Engine.loadConstraints
          .deleteForceSet(param)
          .then((res: any) => {
            loadConstraints.splice(i, 1);
            showMaterialEditor.value = false;
          });
      }
    });
  }
  refreshLoadConstraintsList();
  refreshItemEditor();
}
function force_info_click(
  force: ForceItem | displacementItem,
  item: LoadConstraintsItem
) {
  if (item.type === "force_set") {
    _global.Engine.loadConstraints
      .getForceInfo({ forceitem: force })
      .then((res: any) => {
        selectedMaterial.value = parseForce(res);
        editorProps.value = { ...forceEditorProps };
        propsInitial.value = { ...Force_TYPE_initial };
        clearSelected(item.forceInfo);
        force.is_selected = true;
        refreshLoadConstraintsList();
        refreshItemEditor();
      });
  } else if (item.type === "displacement_set") {
    _global.Engine.loadConstraints
      .getDisplacemnetInfo({ id: parseInt(force.id) })
      .then((res: any) => {
        selectedMaterial.value = parseDisplacement(res);
        editorProps.value = { ...displacementEditorProps };
        propsInitial.value = { ...Displacement_TYPE_initial };
        clearSelected(item.displacementInfo);
        force.is_selected = true;
        refreshLoadConstraintsList();
        refreshItemEditor();
      });
  }
}
function create_force_template(id: string, template_type: any) {
  _global.Engine.loadConstraints
    .createForce({ loads_id: id, type: "force" })
    .then((res: any) => {
      let temForce: any;
      if (template_type === "template1") {
        temForce = {
          ...JSON.parse(JSON.stringify(initialForce)), // 深拷贝initialForce
          name: "ForceTemplate1_" + res["id"],
          id: res["id"],
          magnitude: "2", // 设置新值
          directionX: "1",
          directionY: "0",
          directionZ: "0",
        };
      } else {
        temForce = {
          ...JSON.parse(JSON.stringify(initialForce)), // 深拷贝initialForce
          name: "ForceTemplate2_" + res["id"],
          id: res["id"],
          magnitude: "5", // 设置新值
          directionX: "1",
          directionY: "1",
          directionZ: "0",
        };
      }
      selectedMaterial.value = { ...temForce };
      editorProps.value = { ...forceEditorProps };
      propsInitial.value = { ...Force_TYPE_initial };

      const force_set: ForceItem = reactive<ForceItem>({
        name: temForce["name"],
        id: temForce["id"],
        is_selected: true,
        normal: null,
        value: parseForce(temForce),
      });
      if (loadConstraints.length !== 0) {
        loadConstraints.forEach((q: any) => {
          if (q.id === id && q.forceInfo) {
            if (q.forceInfo.length !== 0) {
              clearSelected(q.forceInfo);
            }
            q.forceInfo.push(force_set);
            console.log("q.forceInfo", q.forceInfo);
          }
        });
      }
      _global.Engine.loadConstraints.modifyForce(temForce).then((res: any) => {
        // @ts-ignore
      });
      refreshLoadConstraintsList();
      refreshItemEditor();
    });
}
function create_force(id: string) {
  _global.Engine.loadConstraints
    .createForce({ loads_id: id, type: "force" })
    .then((res: any) => {
      initialForce.name = res["name"];
      initialForce.id = res["id"];
      selectedMaterial.value = { ...initialForce };
      editorProps.value = { ...forceEditorProps };
      propsInitial.value = { ...Force_TYPE_initial };

      const force_set: ForceItem = reactive<ForceItem>({
        name: res["name"],
        id: res["id"],
        is_selected: true,
        normal: null,
        value: parseForce(res),
      });
      if (loadConstraints.length !== 0) {
        loadConstraints.forEach((q: any) => {
          if (q.id === id && q.forceInfo) {
            if (q.forceInfo.length !== 0) {
              clearSelected(q.forceInfo);
            }
            q.forceInfo.push(force_set);
          }
        });
      }
      refreshLoadConstraintsList();
      refreshItemEditor();
    });
}
function create_force_set(type: string) {
  refreshLoadConstraintsList();
  // showLoadConstraints.value = true;
  _global.Engine.loadConstraints
    .createLoadConstraints({
      modelInfo: "",
      type: "forceSet",
    })
    .then((res: any) => {
      initialLoadConstraint.name = res["name"];
      initialLoadConstraint.id = res["id"];
      initialLoadConstraint.loadConstraintType = "force";
      selectedMaterial.value = { ...initialLoadConstraint };
      editorProps.value = { ...loadConstraintEditorProps };
      propsInitial.value = { ...Load_Constraint_TYPE_initial };
      if (loadConstraints.length !== 0) {
        clearSelected(loadConstraints);
      }
      const force_set: LoadConstraintsItem = reactive<LoadConstraintsItem>({
        name: res["name"],
        id: res["id"],
        is_selected: true,
        type: "force_set",
        value: parseLoadConstraints(res),
        forceInfo: [],
      });
      loadConstraints.push(force_set);
      refreshLoadConstraintsList();
      refreshItemEditor();
    });
}
function create_bcs() {
  refreshLoadConstraintsList();
  // showLoadConstraints.value = true;
  _global.Engine.loadConstraints
    .createBcs({
      modelInfo: "",
      type: "bcsSet",
    })
    .then((res: any) => {
      initialLoadConstraint.name = res["name"];
      initialLoadConstraint.id = res["id"];
      initialLoadConstraint.loadConstraintType = "displacement";
      selectedMaterial.value = { ...initialLoadConstraint };
      editorProps.value = { ...loadConstraintEditorProps };
      propsInitial.value = { ...Load_Constraint_TYPE_initial };
      //@ts-ignore
      selectedMaterial.value.id = res["id"];
      if (loadConstraints.length !== 0) {
        clearSelected(loadConstraints);
      }
      const bcs: LoadConstraintsItem = reactive<LoadConstraintsItem>({
        name: res["name"],
        id: res["id"],
        is_selected: true,
        type: "displacement_set",
        value: parseLoadConstraints(res),
        displacementInfo: [],
      });
      loadConstraints.push(bcs);
      refreshLoadConstraintsList();
      refreshItemEditor();
    });
}
function create_displacement_template(id: string, template_type: any) {
  _global.Engine.loadConstraints
    .createDisplacement({ loads_id: id, type: "displacement" })
    .then((res: any) => {
      let temDisplacement: any;
      if (template_type === "template1") {
        temDisplacement = {
          ...JSON.parse(JSON.stringify(initialDisplacement)), // 深拷贝initialForce
          name: "DispTemplate1_" + res["id"],
          id: res["id"],
          dof1Value: "0",
          dof2Value: "1",
          dof3Value: "1",
          dof4Value: "1",
          dof5Value: "1",
          dof6Value: "1",
        };
      } else {
        temDisplacement = {
          ...JSON.parse(JSON.stringify(initialDisplacement)), // 深拷贝initialForce
          name: "DispTemplate2_" + res["id"],
          id: res["id"],
          dof1Value: "0",
          dof2Value: "0",
          dof3Value: "1",
          dof4Value: "1",
          dof5Value: "1",
          dof6Value: "0",
        };
      }
      selectedMaterial.value = { ...temDisplacement };
      editorProps.value = { ...displacementEditorProps };
      propsInitial.value = { ...Displacement_TYPE_initial };

      const displacement_set: ForceItem = reactive<ForceItem>({
        name: temDisplacement["name"],
        id: temDisplacement["id"],
        is_selected: true,
        normal: {
          dof1: null,
          dof2: null,
          dof3: null,
          dof4: null,
          dof5: null,
          dof6: null,
        },
        value: parseDisplacement(temDisplacement),
      });
      if (loadConstraints.length !== 0) {
        loadConstraints.forEach((q: any) => {
          if (q.id === id && q.displacementInfo) {
            if (q.displacementInfo.length !== 0) {
              clearSelected(q.displacementInfo);
            }
            q.displacementInfo.push(displacement_set);
          }
        });
      }
      _global.Engine.loadConstraints
        .modifyDisplacemnet(temDisplacement)
        .then((res: any) => {});
      refreshLoadConstraintsList();
      refreshItemEditor();
    });
}
function create_displacement(id: string) {
  _global.Engine.loadConstraints
    .createDisplacement({ loads_id: id, type: "displacement" })
    .then((res: any) => {
      initialDisplacement.name = res["name"];
      initialDisplacement.id = res["id"];
      selectedMaterial.value = { ...initialDisplacement };
      editorProps.value = { ...displacementEditorProps };
      propsInitial.value = { ...Displacement_TYPE_initial };

      const displacement_set: ForceItem = reactive<ForceItem>({
        name: res["name"],
        id: res["id"],
        is_selected: true,
        normal: {
          dof1: null,
          dof2: null,
          dof3: null,
          dof4: null,
          dof5: null,
          dof6: null,
        },
        value: parseDisplacement(res),
      });
      if (loadConstraints.length !== 0) {
        loadConstraints.forEach((q: any) => {
          if (q.id === id && q.displacementInfo) {
            if (q.displacementInfo.length !== 0) {
              clearSelected(q.displacementInfo);
            }
            q.displacementInfo.push(displacement_set);
          }
        });
      }
      refreshLoadConstraintsList();
      refreshItemEditor();
    });
}
function update_displacement() {
  _global.Engine.loadConstraints.getAllLoadConstraints().then((res: any) => {
    // 如果为多个数据使用：res.forEach((item: any) => { 下面的代码 })
    initialDisplacement.name = res["name"];
    initialDisplacement.id = res["id"];
    selectedMaterial.value = { ...initialDisplacement };
    editorProps.value = { ...displacementEditorProps };
    propsInitial.value = { ...Displacement_TYPE_initial };

    const displacement_set: ForceItem = reactive<ForceItem>({
      name: res["name"],
      id: res["id"],
      is_selected: true,
      normal: {
        dof1: null,
        dof2: null,
        dof3: null,
        dof4: null,
        dof5: null,
        dof6: null,
      },
      value: selectedMaterial.value,
    });
    if (loadConstraints.length !== 0) {
      loadConstraints.forEach((q: any) => {
        if (q.id === id && q.displacementInfo) {
          if (q.displacementInfo.length !== 0) {
            clearSelected(q.displacementInfo);
          }
          q.displacementInfo.push(displacement_set);
        }
      });
    }
    refreshLoadConstraintsList();
    refreshItemEditor();
  });
}
const temperatures: any[] = [];
function create_temperature_set() {
  selectedMaterial.value = { ...initialTemperature };
  _global.Engine.loadConstraints
    .createTemperatureSet({
      modelInfo: "",
    })
    .then((res: any) => {
      const p = res;
      console.log("temp", p);
      unselectAllItems();
      initialTemperature.name = res["name"];
      initialTemperature.id = res["id"];
      selectedMaterial.value = { ...initialTemperature };
      editorProps.value = { ...temperatureEditorProps };
      propsInitial.value = { ...TEMPERATURE_TYPE_initial };
      let parseResult = parseTemperature(p);
      const temperature = {
        name: p["name"],
        id: p["id"],
        is_selected: true,
        value: parseResult,
        normal: null,
      };
      temperatures.push(temperature);
      refreshLoadConstraintsList();
      refreshItemEditor();
    });
}

function temperatures_click(item: TemperatureItem) {
  item.is_selected = true;
  console.log("item", item);
  selectedMaterial.value = item.value;
  editorProps.value = { ...temperatureEditorProps };
  propsInitial.value = { ...TEMPERATURE_TYPE_initial };
  // clearSelected(loadConstraints);
  refreshLoadConstraintsList();
  refreshItemEditor();
}
async function temperatureItemMenu(
  event: MouseEvent,
  item: TemperatureItem,
  index: number
) {
  const selectedKeys = await Contextmenu.open({
    clientX: event.clientX,
    clientY: event.clientY,
    appear: true,
    configs: [{ key: "delete", label: "删除" }],
  });
  if (selectedKeys) {
    if (selectedKeys[0] === "delete") {
      _global.Engine.loadConstraints
        .deleteTemperatureSet(item.id)
        .then((res: string) => {
          if (temperatures[index].normal) {
            _global.Engine.model.remove(temperatures[index].normal);
          }
          temperatures.splice(index, 1);
          refreshLoadConstraintsList();
        });
    }
  }
}
const nodeCoordinates = reactive({
  nodeCoordinates: [] as NodeCoordinates[],
});
function create_nodeCoordinates() {
  selectedMaterial.value = { ...initialNodeCoordinates };
  _global.Engine.coordinate
    .createNodeCoordinate({
      modelInfo: "",
    })
    .then((res: any) => {
      const p = res;
      console.log("temp", p);
      unselectAllItems();
      initialNodeCoordinates.name = res["name"];
      initialNodeCoordinates.id = res["id"];
      selectedMaterial.value = { ...initialNodeCoordinates };
      editorProps.value = { ...nodeCoordinatesEditorProps };
      propsInitial.value = { ...NODECOORDINATES_TYPE_initial };
      let parseResult = parseNodeCoordinates(p);
      const nodeCoordinate = {
        name: p["name"],
        id: p["id"],
        is_selected: true,
        value: parseResult,
      };
      nodeCoordinates.nodeCoordinates.push(nodeCoordinate);
      refreshLoadCoordinatesList();
      refreshItemEditor();
    });
}

const materialOrientations = reactive({
  materialOrientations: [] as MaterialOrientationsItem[],
});
function create_materialOrientations() {
  selectedMaterial.value = { ...initialMaterialOrientations };
  _global.Engine.coordinate
    .createMaterialOrientation({
      modelInfo: "",
    })
    .then((res: any) => {
      const p = res;
      console.log("temp", p);
      unselectAllItems();
      initialMaterialOrientations.name = res["name"];
      initialMaterialOrientations.id = res["id"];
      selectedMaterial.value = { ...initialMaterialOrientations };
      editorProps.value = { ...materialOrientationsEditorProps };
      propsInitial.value = { ...MATERIALORIENTATIONS_TYPE_initial };
      let parseResult = parseMaterialOrientations(p);
      const materialOrientation = {
        name: p["name"],
        id: p["id"],
        is_selected: true,
        value: parseResult,
      };
      materialOrientations.materialOrientations.push(materialOrientation);
      refreshLoadCoordinatesList();
      refreshItemEditor();
    });
}
function load_constraints_click(item: LoadConstraintsItem) {
  console.log("item", item);
  selectedMaterial.value = item.value;
  editorProps.value = { ...loadConstraintEditorProps };
  propsInitial.value = { ...Load_Constraint_TYPE_initial };
  clearSelected(loadConstraints);
  item.is_selected = true;
  refreshLoadConstraintsList();
  refreshItemEditor();
}
function clearSelected(list: any) {
  list.forEach((a: any) => {
    a.is_selected = false;
  });
}
async function materialItemMenu(
  event: MouseEvent,
  item: MaterialItem,
  index: number
) {
  // 未选择是则返回 null
  const selectedKeys = await Contextmenu.open({
    clientX: event.clientX,
    clientY: event.clientY,
    appear: true,
    configs: [{ key: "delete_material", label: "删除材料卡片" }],
  });

  if (selectedKeys && selectedKeys[0] == "delete_material") {
    // 删除material
    _global.Engine.material.deleteMaterial(item.id).then((res: string) => {
      materials.splice(index, 1);
      refreshMaterialList();
      if (item.is_selected) {
        item.is_selected = false;
        showDefaultItemEditor();
      }
    });
  }
}
async function propertyMenu(event: MouseEvent) {
  // 未选择是则返回 null
  const selectedKeys = await Contextmenu.open({
    clientX: event.clientX,
    clientY: event.clientY,
    appear: true,
    configs: [
      { key: "create_property", label: "创建属性卡片" },
      { key: "batch_rename_properties", label: "批量重命名" },
    ],
  });
  if (selectedKeys && selectedKeys[0] == "create_property") {
    create_property();
  } else if (selectedKeys && selectedKeys[0] == "batch_rename_properties") {
    rename_properties();
  }
}
async function propertyItemMenu(
  event: MouseEvent,
  item: MaterialItem,
  index: number
) {
  // 未选择是则返回 null
  const selectedKeys = await Contextmenu.open({
    clientX: event.clientX,
    clientY: event.clientY,
    appear: true,
    configs: [{ key: "delete_property", label: "删除属性卡片" }],
  });

  if (selectedKeys && selectedKeys[0] == "delete_property") {
    // 删除property
    _global.Engine.property.deleteProperty(item.id).then((res: string) => {
      properties.splice(index, 1);
      refreshPropertyList();
      if (item.is_selected) {
        item.is_selected = false;
        showDefaultItemEditor();
      }
    });
  }
}
function property_click(item: PropertyItem) {
  unselectAllItems();
  item.is_selected = true;
  console.log("item.value", item.value);
  selectedMaterial.value = item.value;
  editorProps.value = { ...propertyEditorProps };
  propsInitial.value = { ...PROPERTY_TYPE_initial };
  refreshMaterialList();
  refreshItemEditor();
}

function unselectProperties() {
  properties.forEach((item) => {
    item.is_selected = false;
  });
}

function unselectSets() {
  sets.forEach((item) => {
    item.is_selected = false;
  });
}

//todo 创建属性
function create_property() {
  selectedMaterial.value = { ...initialPropertyPSHELL };
  editorProps.value = { ...propertyEditorProps };
  propsInitial.value = { ...PROPERTY_TYPE_initial };
  let values = {};
  _global.Engine.property
    .createProperty(values)
    .then((res: any) => {
      const p = res.property;
      unselectAllItems();
      let parseResult = parseProperty(p);
      const property = {
        name: p["name"],
        id: p["id"],
        is_selected: true,
        value: parseResult,
      };
      // selectedMaterial中不能有任何值为undefined属性。
      selectedMaterial.value = property.value; // 这一步出错了
      properties.push(property);
      refreshPropertyList();
      refreshMaterialList();
      refreshItemEditor();
    })
    .catch((errorMsg) => {
      alert(errorMsg);
    });
}

function material_click(item: MaterialItem) {
  unselectAllItems();
  item.is_selected = true;
  selectedMaterial.value = item.value;
  editorProps.value = { ...materialEditorProps };
  propsInitial.value = { ...MATERIAL_TYPE_initial };
  refreshMaterialList();
  refreshItemEditor();
}

//场功能
const fields: any[] = [];
async function fieldMenu(event: MouseEvent) {
  // 未选择是则返回 null
  const selectedKeys = await Contextmenu.open({
    clientX: event.clientX,
    clientY: event.clientY,
    appear: true,
    configs: [
      { key: "create_field", label: "创建场卡片" },
      { key: "batch_rename_fields", label: "批量重命名" },
    ],
  });
  if (selectedKeys && selectedKeys[0] == "create_field") {
    create_field();
  }
  // } else if (selectedKeys && selectedKeys[0] == "batch_rename_properties") {
  //   rename_properties();
  // }
}
function create_field() {
  selectedMaterial.value = { ...initialField };
  _global.Engine.field
    .createField({
      modelInfo: "",
    })
    .then((res: any) => {
      const p = res;
      console.log("temp", p);
      unselectAllItems();
      initialField.name = res["name"];
      initialField.id = res["id"];
      selectedMaterial.value = { ...initialField };
      editorProps.value = { ...fieldEditorProps };
      propsInitial.value = { ...FIELD_TYPE_initial };
      let parseResult = parseField(p);
      const field = {
        name: p["name"],
        id: p["id"],
        is_selected: true,
        value: parseResult,
      };
      fields.push(field);
      refreshFieldList();
      refreshItemEditor();
    });
}

function field_click(item: FieldItem) {
  item.is_selected = true;
  console.log("item", item);
  selectedMaterial.value = item.value;
  editorProps.value = { ...fieldEditorProps };
  propsInitial.value = { ...FIELD_TYPE_initial };
  // clearSelected(loadConstraints);
  refreshFieldList();
  refreshItemEditor();
}
async function fieldItemMenu(
  event: MouseEvent,
  item: FieldItem,
  index: number
) {
  const selectedKeys = await Contextmenu.open({
    clientX: event.clientX,
    clientY: event.clientY,
    appear: true,
    configs: [{ key: "delete", label: "删除" }],
  });
  if (selectedKeys) {
    if (selectedKeys[0] === "delete") {
      _global.Engine.field.deleteField(item.id).then((res: string) => {
        // if (temperatures[index].normal) {
        //   _global.Engine.model.remove(temperatures[index].normal);
        // }
        fields.splice(index, 1);
        console.log("fields", fields);
        refreshFieldList();
        showDefaultItemEditor();
      });
    }
  }
}
// TODO: 添加对集合的判断
function is_set(item: any) {
  return item["itemType"] == "set";
}
function is_material(item: any) {
  if (item.type) {
    return item.type == "MAT1" || item.type == "MAT8" || item.type == "MAT9";
  }
  return false;
}

function is_property(item: any) {
  if (item.type) {
    return (
      item.type == "PCOMP" || item.type == "PBUSH" || item.type == "PSHELL"
    );
  }
  return false;
}

function getUpdateValues(item: Record<string, any>) {
  const values: Record<string, any> = {};
  if (item.name && item.name != selectedMaterial.value.name) {
    // 如果名字发生了修改，需要记录一下名字
    values.name = item.name;
  }
  if (item.color && typeof item.color == "string") {
    // 要把颜色改为格宇可以接受的颜色值
    values.color = rgb255str2rgb1arr(item.color);
  }
  for (let key in item) {
    if (key == "name" || key == "color" || key == "id") {
      // 这些都处理过了。
      continue;
    }
    if (key == "stiffness") {
      values["K-Line"] = item[key].value;
      if (item[key].value) {
        for (let i = 1; i <= 6; i++) {
          values["k" + i] = item[key]["k" + i];
        }
      }
      continue;
    }
    if (key == "numOfPlies") {
      values["numOfPlies"] = item[key].value;
      if (values["numOfPlies"] == 1) {
        // 一层的层压板
        values["material"] = item[key].material;
        values["thickness"] = item[key].thickness;
        values["theta"] = item[key].theta;
        values["sout"] = item[key].sout;
      }
      continue;
    }
    values[key] = item[key];
  }
  return values;
}

function handleUpdate(item: any) {
  if (is_material(item) || is_property(item) || is_set(item)) {
    const id = parseInt(item.id);
    const values = getUpdateValues(item);
    console.log("update values:", values);
    if (is_material(item)) {
      // 修改material
      _global.Engine.material
        .modifyMaterial(id, values)
        .then((res: string) => {
          console.log("update res:", res);
          if (item.name) {
            selectedMaterial.value.name = item.name;
          }
          if (item.color) {
            selectedMaterial.value.color = item.color;
          }
          materials.forEach((material_item) => {
            if (material_item.id == id) {
              material_item.value = parseMaterial(res.material);
              selectedMaterial.value = material_item.value;
              if (item.name) {
                // 按照返回的value值更改所有property属性
                material_item.name = item.name;
              }
            }
          });
          selectedMaterial.value.name = item.name;
          materials.forEach((material_item: MaterialItem) => {
            if (material_item.id == id) {
              // forEach循环中不能使用break。
              material_item.name = item.name;
            }
          });
          refreshMaterialList();
          refreshItemEditor();
        })
        .catch((errMsg: string) => {
          alert(errMsg);
        });
    } else if (is_property(item)) {
      console.log("update values:", values);
      // 修改property
      _global.Engine.property
        .modifyProperty(id, values)
        .then((res: string) => {
          if (item.name) {
            selectedMaterial.value.name = item.name;
          }
          if (item.color) {
            selectedMaterial.value.color = item.color;
          }
          properties.forEach((property_item) => {
            if (property_item.id == id) {
              property_item.value = parseProperty(res.property);
              selectedMaterial.value = property_item.value;
              if (item.name) {
                // 按照返回的value值更改所有property属性
                property_item.name = item.name;
              }
              if (item.color) {
                const itemColor = str_or_rgb1arr2gyColor(item.color);
                const entity_ids = entityPropRecorder.getEntityIds(
                  property_item.id
                );
                entity_ids.forEach((id) => {
                  _global.Engine.color.set_entity_color(
                    id,
                    color2rgb255arr(itemColor)
                  );
                });
              }
            }
          });
          refreshPropertyList();
          refreshItemEditor();
        })
        .catch((errMsg: string) => {
          alert(errMsg);
        });
    }
    // @ts-ignore
  }
  if (item.setType) {
    selectedMaterial.value = parseSet(item);
    const id = parseInt(item.id);
    _global.Engine.set
      .modifySet(id, item)
      .then((res: string) => {
        sets.forEach((set_item) => {
          if (set_item.id == id) {
            if (item.name) {
              set_item.name = item.name;
            }
            set_item.value = parseSet(item);
          }
        });
        // console.log("sets", sets);
        refreshSetList();
        refreshItemEditor();
      })
      .catch((errMsg: string) => {
        alert(errMsg);
      });
  }
  if (item.loadConstraintType === "force") {
    loadConstraints.forEach((load_constrains: any) => {
      if (
        item.id === load_constrains.id &&
        load_constrains.type === "force_set"
      ) {
        load_constrains.name = item.name;
        load_constrains.value = item;
      }
    });
  }
  if (item.loadConstraintType === "displacement") {
    loadConstraints.forEach((load_constrains: any) => {
      if (
        item.id === load_constrains.id &&
        load_constrains.type === "displacement_set"
      ) {
        load_constrains.name = item.name;
        load_constrains.value = item;
      }
    });
  }
  if (item.forceType) {
    selectedMaterial.value = parseForce(item);
    // if (item.applyTo === 1 || item.applyTo === 0) {
    //   // coreStore.setEngineState(1);
    //   _global.Engine.selectBoxComp.enableSelectByBox("meshPoint");
    // } else if (item.applyTo === 2) {
    //   coreStore.setEngineState(3);
    // } else if (item.applyTo === 3) {
    //   coreStore.setEngineState(0);
    // }
    item.node = _global.Engine.selectBoxComp.selectedPoints;
    const pointsData: number[] = [];
    const normalData: number[] = [];
    _global.Engine.selectBoxComp.selectedPoints.forEach((a) => {
      pointsData.push(a.x, a.y, a.z);
      normalData.push(
        Number(item.directionX),
        Number(item.directionY),
        Number(item.directionZ)
      );
    });
    _global.Engine.loadConstraints.modifyForce(item).then((res: any) => {
      const pointsData: number[] = [];
      const normalData: number[] = [];
      _global.Engine.selectBoxComp.selectedPoints.forEach((a) => {
        pointsData.push(a.x, a.y, a.z);
        normalData.push(
          Number(item.directionX),
          Number(item.directionY),
          Number(item.directionZ)
        );
      });
      loadConstraints.forEach((load_constrains: any) => {
        if (
          load_constrains.forceInfo &&
          load_constrains.forceInfo.length !== 0
        ) {
          load_constrains.forceInfo.forEach((e: any) => {
            if (e.id === item.id) {
              e.name = item.name;
              if (item.node.length == 0) {
                refreshLoadConstraintsList;
                return;
              }
              if (e.normal) {
                _global.Engine.model.remove(e.normal);
                e.normal = new TArrow(normalData, pointsData);
              } else {
                e.normal = new TArrow(normalData, pointsData);
              }
              _global.Engine.model.add(e.normal);
            }
          });
        }
      });
      // @ts-ignore
    });
  }
  if (item.displacemnetType) {
    selectedMaterial.value = parseDisplacement(item);
    // if (item.applyTo === 1 || item.applyTo === 0) {
    //   // coreStore.setEngineState(1);
    //   _global.Engine.selectBoxComp.enableSelectByBox("meshPoint");
    // } else if (item.applyTo === 2) {
    //   coreStore.setEngineState(3);
    // } else if (item.applyTo === 3) {
    //   coreStore.setEngineState(0);
    // }
    item.node = _global.Engine.selectBoxComp.selectedPoints;
    _global.Engine.loadConstraints.modifyDisplacemnet(item).then((res: any) => {
      const pointsData: Vector3[] = [];
      _global.Engine.selectBoxComp.selectedPoints.forEach((a) => {
        pointsData.push([a.x, a.y, a.z]);
      });
      loadConstraints.forEach((load_constrains: any) => {
        if (
          load_constrains.displacementInfo &&
          load_constrains.displacementInfo.length !== 0
        ) {
          load_constrains.displacementInfo.forEach((e: any) => {
            if (e.id === item.id) {
              e.name = item.name;
              if (item.node.length == 0) {
                refreshLoadConstraintsList;
                return;
              }
              if (!e.normal.dof1) {
                e.normal.dof1 = new TCell([1, 0, 0], [1, 0, 0], pointsData);
              }
              if (!e.normal.dof2) {
                e.normal.dof2 = new TCell([0, 1, 0], [0, 1, 0], pointsData);
              }
              if (!e.normal.dof3) {
                e.normal.dof3 = new TCell([0, 0, 1], [0, 0, 1], pointsData);
              }
              if (!e.normal.dof4) {
                e.normal.dof4 = new TCell(
                  [1, 0, 0],
                  [0.5, 0.5, 0.5],
                  e.normal.dof1.dofNext
                );
              }
              if (!e.normal.dof5) {
                e.normal.dof5 = new TCell(
                  [0, 1, 0],
                  [0.5, 0.5, 0.5],
                  e.normal.dof2.dofNext
                );
              }
              if (!e.normal.dof6) {
                e.normal.dof6 = new TCell(
                  [0, 0, 1],
                  [0.5, 0.5, 0.5],
                  e.normal.dof3.dofNext
                );
              }
              if (item.dof1) {
                _global.Engine.model.add(e.normal.dof1);
              } else {
                _global.Engine.model.remove(e.normal?.dof1);
              }
              if (item.dof2) {
                _global.Engine.model.add(e.normal.dof2);
              } else {
                _global.Engine.model.remove(e.normal?.dof2);
              }
              if (item.dof3) {
                _global.Engine.model.add(e.normal.dof3);
              } else {
                _global.Engine.model.remove(e.normal?.dof3);
              }
              if (item.dof4) {
                _global.Engine.model.add(e.normal.dof4);
              } else {
                _global.Engine.model.remove(e.normal?.dof4);
              }
              if (item.dof5) {
                _global.Engine.model.add(e.normal.dof5);
              } else {
                _global.Engine.model.remove(e.normal?.dof5);
              }
              if (item.dof6) {
                _global.Engine.model.add(e.normal.dof6);
              } else {
                _global.Engine.model.remove(e.normal?.dof6);
              }
            }
          });
        }
      });
    });
  } else {
    // TODO: alert("未知类型");
  }
  // 输出块卡片
  if (item.output) {
    const id = parseInt(item.id);
    const values = getUpdateValues(item);
    _global.Engine.outputblock
      .modifyOutputblock(id, values)
      .then((res: string) => {
        if (item.name) {
          selectedMaterial.value.name = item.name;
        }
        outputblocks.forEach((outputblock_item) => {
          if (outputblock_item.id == id) {
            if (item.name) {
              outputblock_item.name = item.name;
            }
          }
        });
        refreshOutputblockList();
        refreshItemEditor();
      })
      .catch((errMsg: string) => {
        alert(errMsg);
      });
  }
  if (item.type == "Restart") {
    const id = parseInt(item.id);
    const values = getUpdateValues(item);
    _global.Engine.card
      .modifyCard(id, values)
      .then((res: string) => {
        if (item.name) {
          selectedMaterial.value.name = item.name;
        }
        cards.forEach((card_item) => {
          if (card_item.id == id) {
            if (item.name) {
              card_item.name = item.name;
            }
          }
        });
        refreshCardList();
        refreshItemEditor();
      })
      .catch((errMsg: string) => {
        alert(errMsg);
      });
  }
  //坐标系
  if (item.coordinateType) {
    const id = item.id;
    const values = getUpdateValues(item);
    _global.Engine.coordinate
      .modify_coordinatename(id, values)
      .then((res: string) => {
        // console.log("res", res);
        if (item.name) {
          selectedMaterial.value.name = item.name;
        }
        coordinates.coordinates.forEach((coordinate_item) => {
          if (coordinate_item.id == id) {
            if (item.name) {
              coordinate_item.name = item.name;
            }
          }
        });
        refreshLoadCoordinatesList();
        refreshItemEditor();
      })
      .catch((errMsg: string) => {
        alert(errMsg);
      });
  }
  if (item.temperature_type) {
    selectedMaterial.value = parseTemperature(item);
    const id = parseInt(item.id);
    _global.Engine.loadConstraints
      .modifyTemperature(id, item)
      .then((res: string) => {
        temperatures.forEach((temperature_item) => {
          if (temperature_item.id == id) {
            if (item.name) {
              temperature_item.name = item.name;
            }
            if (item.magnitude) {
              temperature_item.magnitude = item.magnitude;
            }
            temperature_item.value = parseTemperature(item);
          }
        });
        // console.log("temperatures", temperatures);
        refreshLoadConstraintsList();
        refreshItemEditor();
      })
      .catch((errMsg: string) => {
        alert(errMsg);
      });
  }
  if (item.NCSselectNodes) {
    selectedMaterial.value = parseNodeCoordinates(item);
    const id = parseInt(item.id);
    _global.Engine.coordinate
      .modify_nodeCoordinate(id, item)
      .then((res: string) => {
        // console.log("update res:", res);
        nodeCoordinates.nodeCoordinates.forEach((nodeCoordinate_item) => {
          if (nodeCoordinate_item.id == id) {
            if (item.name) {
              nodeCoordinate_item.name = item.name;
            }
            nodeCoordinate_item.value = parseNodeCoordinates(item);
          }
        });
        refreshCoordinateList();
        refreshItemEditor();
      })
      .catch((errMsg: string) => {
        alert(errMsg);
      });
  }
  if (item.MOselectElems) {
    // console.log("MO", item);
    selectedMaterial.value = parseMaterialOrientations(item);
    const id = parseInt(item.id);
    _global.Engine.coordinate
      .modifyMaterialOrientation(id, item)
      .then((res: string) => {
        // console.log("update res:", res);
        materialOrientations.materialOrientations.forEach(
          (materialOrientation_item) => {
            if (materialOrientation_item.id == id) {
              if (item.name) {
                materialOrientation_item.name = item.name;
              }
              materialOrientation_item.value = parseMaterialOrientations(item);
            }
          }
        );
        refreshCoordinateList();
        refreshItemEditor();
      })
      .catch((errMsg: string) => {
        alert(errMsg);
      });
  }
  //场
  if (item.field_type) {
    // console.log("item.field_type", item);
    selectedMaterial.value = parseField(item);
    const id = parseInt(item.id);
    _global.Engine.field
      .modifyField(id, item)
      .then((res: any) => {
        console.log("res", res);
        fields.forEach((field_item) => {
          if (field_item.id == id) {
            field_item.name = item.name;
            field_item.value = parseField(res);
            field_item.value.fieldFile = item.fieldFile;
            field_item.value.realize.fieldColumn = item.realize.fieldColumn;
            // field_item.value.realize.fieldNodes = item.realize.fieldNodes;
            selectedMaterial.value = field_item.value;
          }
        });
        // console.log("fields", fields);
        refreshFieldList();
        refreshItemEditor();
      })
      .catch((errMsg: string) => {
        alert(errMsg);
      });
  }
}
async function CoordinateItemMenu(
  event: MouseEvent,
  item: CoordinateItem,
  index: number
) {
  // 未选择是则返回 null
  const selectedKeys = await Contextmenu.open({
    clientX: event.clientX,
    clientY: event.clientY,
    appear: true,
    configs: [{ key: "delete_coordinate", label: "删除坐标系卡片" }],
  });

  if (selectedKeys && selectedKeys[0] == "delete_coordinate") {
    // 删除material
    _global.Engine.coordinate
      .deleteCoordinate(Number(item.id))
      .then((res: string) => {
        if (coordinates.coordinates[index].xAxis) {
          _global.Engine.model.remove(coordinates.coordinates[index].xAxis);
        }
        if (coordinates.coordinates[index].yAxis) {
          _global.Engine.model.remove(coordinates.coordinates[index].yAxis);
        }
        if (coordinates.coordinates[index].zAxis) {
          _global.Engine.model.remove(coordinates.coordinates[index].zAxis);
        }
        coordinates.coordinates.splice(index, 1);
        refreshCoordinateList();
        if (item.is_selected) {
          item.is_selected = false;
          showDefaultItemEditor();
        }
      });
  }
}
async function NodeCoordinateItemMenu(
  event: MouseEvent,
  item: NodeCoordinates,
  index: number
) {
  // 未选择是则返回 null
  const selectedKeys = await Contextmenu.open({
    clientX: event.clientX,
    clientY: event.clientY,
    appear: true,
    configs: [{ key: "delete_nodeCoordinate", label: "删除" }],
  });

  if (selectedKeys && selectedKeys[0] == "delete_nodeCoordinate") {
    // 删除material
    _global.Engine.coordinate
      .deleteNodeCoordinate(item.id)
      .then((res: string) => {
        console.log(res);
        nodeCoordinates.nodeCoordinates.splice(index, 1);
        console.log(nodeCoordinates);
        refreshCoordinateList();
        if (item.is_selected) {
          item.is_selected = false;
          showDefaultItemEditor();
        }
      });
  }
}
async function MaterialOrientationItemMenu(
  event: MouseEvent,
  item: NodeCoordinates,
  index: number
) {
  // 未选择是则返回 null
  const selectedKeys = await Contextmenu.open({
    clientX: event.clientX,
    clientY: event.clientY,
    appear: true,
    configs: [{ key: "delete_materialOrientation", label: "删除" }],
  });

  if (selectedKeys && selectedKeys[0] == "delete_materialOrientation") {
    // 删除material
    _global.Engine.coordinate
      .deleteMaterialOrientation(item.id)
      .then((res: string) => {
        console.log(res);
        materialOrientations.materialOrientations.splice(index, 1);
        console.log(materialOrientations);
        refreshCoordinateList();
        if (item.is_selected) {
          item.is_selected = false;
          showDefaultItemEditor();
        }
      });
  }
}
function showDefaultItemEditor() {
  showMaterialEditor.value = true;
  nextTick(() => {
    showMaterialEditor.value = false;
  });
}

function refreshItemEditor() {
  showMaterialEditor.value = false;
  nextTick(() => {
    showMaterialEditor.value = true;
  });
}

// 刷新材料卡片列表
function refreshMaterialList() {
  showMaterial.value = false;
  nextTick(() => {
    showMaterial.value = true;
  });
}
function refreshLoadConstraintsList() {
  showLoadConstraints.value = false;
  nextTick(() => {
    showLoadConstraints.value = true;
  });
}
function refreshFieldList() {
  showField.value = false;
  nextTick(() => {
    showField.value = true;
  });
}
function refreshLoadCoordinatesList() {
  showLoadCoordinates.value = false;
  nextTick(() => {
    showLoadCoordinates.value = true;
  });
}

// 以下是属性的部分
const properties: any[] = [];
// 连接后台时访问一次属性属性
coreStore.Notify.subscribe(({ event }) => {
  if (event === "engine_ready") {
    _global.Engine.hooks.onConnected(() => {
      update_sets();
    });
  }
});

// 注册回调函数，访问后端得到属性卡片数据，并塞进properties中
function rename_properties() {
  const prefix = ruleStore.propertyNamePrefix;
  const suffix = ruleStore.propertyNameSuffix;
  if (!prefix && !suffix) return;
  _global.Engine.property
    .batchRenameProperties(prefix, suffix, properties)
    .then((properties_ins: any) => {
      console.log("properties_ins", properties_ins);
      properties_ins = properties_ins.result;
      // materials.length = 0;
      for (let property_ins of properties_ins) {
        const new_value = parseProperty(property_ins);
        properties.forEach((property) => {
          if (property.id == property_ins.id) {
            property.name = property_ins.name;
            property.value = new_value;
          }
        });
      }
      refreshPropertyList();
    });
}
// 刷新属性列表
function refreshPropertyList() {
  showProperty.value = false;
  nextTick(() => {
    showProperty.value = true;
  });
}

// 创建输出块卡片
const showOutputblock = ref(false);
const outputblocks: any[] = [];
// 连接后台时访问一次属性属性
coreStore.Notify.subscribe(({ event }) => {
  if (event === "engine_ready") {
    _global.Engine.hooks.onConnected(() => {
      update_outputblocks();
    });
  }
});
async function outputblockMenu(event: MouseEvent) {
  // 未选择是则返回 null
  const selectedKeys = await Contextmenu.open({
    clientX: event.clientX,
    clientY: event.clientY,
    appear: true,
    configs: [
      { key: "create_outputblock", label: "创建输出块卡片" },
      { key: "get_all_outputblocks", label: "刷新输出块列表" },
    ],
  });
  if (selectedKeys && selectedKeys[0] == "create_outputblock") {
    create_outputblock();
  } else if (selectedKeys && selectedKeys[0] == "get_all_outputblocks") {
    update_outputblocks();
  }
}
function create_outputblock() {
  // selectedMaterial.value = { ...initialOutput };
  // editorProps.value = { ...outputEditorProps };
  // propsInitial.value = { ...OUTPUTBLOCK_TYPE_initial };
  let values = {};
  _global.Engine.outputblock
    .createOutputblock(values)
    .then((res: any) => {
      const p = res.outputblock;
      unselectAllItems();

      let parseResult = parseOutputblock(p);
      const outputblock = {
        name: p["name"],
        id: p["id"],
        is_selected: true,
        value: parseResult,
      };

      // selectedMaterial中不能有任何值为undefined属性。
      selectedMaterial.value = outputblock.value; // 这一步出错了
      editorProps.value = { ...outputEditorProps };
      propsInitial.value = { ...OUTPUTBLOCK_TYPE_initial };
      outputblocks.push(outputblock);
      refreshOutputblockList();
      refreshPropertyList();
      refreshMaterialList();
      refreshItemEditor();
    })
    .catch((errorMsg) => {
      alert(errorMsg);
    });
}
function update_outputblocks() {
  _global.Engine.outputblock
    .getAllOutputblocks()
    .then((outputblocks_ins: any) => {
      outputblocks_ins = outputblocks_ins.outputblock;
      outputblocks.length = 0;
      for (let outputblock of outputblocks_ins) {
        const p = {
          name: "材料B",
          id: 958,
          is_selected: false,
          value: parseOutputblock(outputblock),
        };
        p.name = outputblock["name"];
        p.id = outputblock["id"];
        outputblocks.push(p);
      }
      refreshOutputblockList();
    });
}
function refreshOutputblockList() {
  showOutputblock.value = false;
  nextTick(() => {
    showOutputblock.value = true;
  });
}
async function outputblockItemMenu(
  event: MouseEvent,
  item: OutputblockItem,
  index: number
) {
  // 未选择是则返回 null
  const selectedKeys = await Contextmenu.open({
    clientX: event.clientX,
    clientY: event.clientY,
    appear: true,
    configs: [{ key: "delete_outputblock", label: "删除输出块卡片" }],
  });

  if (selectedKeys && selectedKeys[0] == "delete_outputblock") {
    _global.Engine.outputblock
      .deleteOutputblock(item.id)
      .then((res: string) => {
        outputblocks.splice(index, 1);
        refreshOutputblockList();
        if (item.is_selected) {
          item.is_selected = false;
          showDefaultItemEditor();
        }
      });
  }
}
function outputblock_click(item: OutputblockItem) {
  // unselectAllItems();
  item.is_selected = true;
  selectedMaterial.value = item.value;
  editorProps.value = { ...outputEditorProps };
  propsInitial.value = { ...OUTPUTBLOCK_TYPE_initial };
  refreshOutputblockList;
  refreshMaterialList();
  refreshItemEditor();
}
interface OutputblockItem {
  name: string;
  id: number;
  is_selected: boolean;
  value: SelectMaterial;
}

// 创建卡片
const showCard = ref(false);
const cards: any[] = [];
async function cardMenu(event: MouseEvent) {
  // 未选择是则返回 null
  const selectedKeys = await Contextmenu.open({
    clientX: event.clientX,
    clientY: event.clientY,
    appear: true,
    configs: [{ key: "create_card", label: "创建卡片" }],
  });
  if (selectedKeys && selectedKeys[0] == "create_card") {
    create_card();
  }
}
function create_card() {
  let values = {};
  _global.Engine.card
    .createCard(values)
    .then((res: any) => {
      const p = res;
      unselectAllItems();

      let parseResult = parseCard(p);
      const card = {
        name: p["name"],
        id: p["id"],
        is_selected: true,
        value: parseResult,
      };

      // selectedMaterial中不能有任何值为undefined属性。
      selectedMaterial.value = card.value; // 这一步出错了
      editorProps.value = { ...cardEditorProps };
      propsInitial.value = { ...CARD_TYPE_initial };
      cards.push(card);
      refreshCardList();
      refreshOutputblockList();
      refreshPropertyList();
      refreshMaterialList();
      refreshItemEditor();
    })
    .catch((errorMsg) => {
      alert(errorMsg);
    });
}

function refreshCardList() {
  showCard.value = false;
  nextTick(() => {
    showCard.value = true;
  });
}
async function cardItemMenu(event: MouseEvent, item: CardItem, index: number) {
  // 未选择是则返回 null
  const selectedKeys = await Contextmenu.open({
    clientX: event.clientX,
    clientY: event.clientY,
    appear: true,
    configs: [{ key: "delete_card", label: "删除卡片" }],
  });

  if (selectedKeys && selectedKeys[0] == "delete_card") {
    _global.Engine.card.deleteCard(item.id).then((res: string) => {
      cards.splice(index, 1);
      refreshCardList();
      if (item.is_selected) {
        item.is_selected = false;
        showDefaultItemEditor();
      }
    });
  }
}
function card_click(item: CardItem) {
  // unselectAllItems();
  item.is_selected = true;
  selectedMaterial.value = item.value;
  editorProps.value = { ...cardEditorProps };
  propsInitial.value = { ...CARD_TYPE_initial };
  refreshCardList;
  refreshOutputblockList;
  refreshMaterialList();
  refreshItemEditor();
}
interface CardItem {
  name: string;
  id: number;
  is_selected: boolean;
  value: SelectMaterial;
}

/**
 * @点击卡片时，会触发这个函数，将卡片中的数据传递给编辑器。
 */
let selectedNode: SelectedNode = {
  originalNode: undefined,
  zNode: undefined,
  xzPlanePoint: undefined,
};

function handleInsideClick(v: any) {
  if (v.target === "base_material") {
    coreStore.materialSelectModalActive = true;
  }
  if (v.target === "numOfPlies-editor") {
    coreStore.layerEditorModalActive = true;
  }
  if (
    v.target === "originalNode" ||
    v.target === "zNode" ||
    v.target === "xzPlanePoint"
  ) {
    const selectedPoints = _global.Engine.selectBoxComp.selectedPoints.map(
      (value) => {
        return {
          nodeId: value.nodeId,
          partId: value.partId,
          x: value.x,
          y: value.y,
          z: value.z,
        };
      }
    );
    if (selectedPoints.length <= 0) {
      alert("请选择一个点");
      return;
    } else {
      switch (v.target) {
        case "originalNode":
          selectedNode.originalNode = selectedPoints[selectedPoints.length - 1];
          console.log("selectedNode", selectedNode);
          _global.Engine.coordinate.modifyCoordinate(
            {
              partId: selectedNode.originalNode.partId,
              nodeId: selectedNode.originalNode.nodeId,
            },
            selectedMaterial.value.name,
            "originSelectObjectsSet"
          );
          selectedPoints.length = 0;
          break;
        case "zNode":
          selectedNode.zNode = selectedPoints[selectedPoints.length - 1];
          _global.Engine.coordinate.modifyCoordinate(
            {
              partId: selectedNode.zNode.partId,
              nodeId: selectedNode.zNode.nodeId,
            },
            selectedMaterial.value.name,
            "zAxisSelectObjectsSet"
          );
          selectedPoints.length = 0;
          break;
        case "xzPlanePoint":
          selectedNode.xzPlanePoint = selectedPoints[selectedPoints.length - 1];
          _global.Engine.coordinate.modifyCoordinate(
            {
              partId: selectedNode.xzPlanePoint.partId,
              nodeId: selectedNode.xzPlanePoint.nodeId,
            },
            selectedMaterial.value.name,
            "xZPlaneSelectObjectsSet"
          );
          selectedPoints.length = 0;
          break;
        default:
          console.warn("未知的 target 值:", v.target);
      }
      const id = selectedMaterial.value["id"];
      coordinates.coordinates.forEach((coordinate_item) => {
        if (coordinate_item.id == id) {
          coordinate_item.originalNode = selectedNode.originalNode;
          coordinate_item.zNode = selectedNode.zNode;
          coordinate_item.xzPlanePoint = selectedNode.xzPlanePoint;
          if (selectedNode.originalNode?.nodeId != undefined) {
            coordinate_item.value.originalNode =
              "" + selectedNode.originalNode?.nodeId;
          }
          if (selectedNode.zNode?.nodeId != undefined) {
            coordinate_item.value.zNode = "" + selectedNode.zNode?.nodeId;
          }
          if (selectedNode.xzPlanePoint?.nodeId != undefined) {
            coordinate_item.value.xzPlanePoint =
              "" + selectedNode.xzPlanePoint?.nodeId;
          }
          selectedMaterial.value = coordinate_item.value;
          refreshItemEditor();
          // console.log("coordinate_item", coordinate_item);
          countCoordinate(parseInt(id), coordinate_item);
        }
      });
      _global.Engine.selectBoxComp.resetSelectedMeshPoint();
    }
  }
  // 设置温度
  if (v.target === "temperatureSelectObjects") {
    const values = selectedMaterial.value;
    const node = _global.Engine.selectBoxComp.selectedPoints;
    // console.log("item.node", node);
    _global.Engine.loadConstraints
      .setTemperature(node, values)
      .then((res: string) => {
        // console.log("resetTem", res);
        const pointsData: number[] = [];
        const normalData: number[] = [];
        _global.Engine.selectBoxComp.selectedPoints.forEach((a) => {
          pointsData.push(a.x, a.y, a.z);
          normalData.push(Number(0), Number(0), Number(-1));
        });
        temperatures.forEach((temperature_item) => {
          if (temperature_item.id == values.id) {
            if (temperature_item.normal) {
              _global.Engine.model.remove(temperature_item.normal);
              temperature_item.normal = new TArrow(normalData, pointsData, {
                tipLength: 0,
                tipRadius: 0,
                shaftResolution: 16,
              });
            } else {
              temperature_item.normal = new TArrow(normalData, pointsData, {
                tipLength: 0,
                tipRadius: 0,
                shaftResolution: 16,
              });
            }
            _global.Engine.model.add(temperature_item.normal);
          }
        });
        _global.Engine.selectBoxComp.resetSelectedMeshPoint();
        // console.log("pointdata", pointsData);
        refreshLoadConstraintsList();
        refreshItemEditor();
      })
      .catch((errMsg: string) => {
        alert(errMsg);
      });
  }
  //设置节点坐标系
  if (v.target == "NCSselectNodes") {
    const values = selectedMaterial.value;
    const node = _global.Engine.selectBoxComp.selectedPoints;
    // console.log("item.node", node);
    _global.Engine.coordinate
      .set_nodeCoordinate(node, values)
      .then((res: string) => {
        // console.log("节点坐标系集合", res);
      });
    _global.Engine.selectBoxComp.resetSelectedMeshPoint();
    refreshLoadCoordinatesList();
    refreshItemEditor();
  }
  //载荷约束取消选点
  if (v.target === "ForceChooseSubject") {
    let node: any[] = [];
    let item = { ...parseForce(selectedMaterial.value), node };
    if (
      item.magnitude === "0.0" &&
      item.directionX === "0.0" &&
      item.directionY === "0.0" &&
      item.directionZ === "0.0"
    ) {
      _global.Engine.selectBoxComp.resetSelectedMeshPoint();
    } else {
      item.node = _global.Engine.selectBoxComp.selectedPoints;
      const pointsData: number[] = [];
      const normalData: number[] = [];
      _global.Engine.selectBoxComp.selectedPoints.forEach((a) => {
        pointsData.push(a.x, a.y, a.z);
        normalData.push(
          Number(item.directionX),
          Number(item.directionY),
          Number(item.directionZ)
        );
      });
      _global.Engine.loadConstraints.modifyForce(item).then((res: any) => {
        const pointsData: number[] = [];
        const normalData: number[] = [];
        _global.Engine.selectBoxComp.selectedPoints.forEach((a) => {
          pointsData.push(a.x, a.y, a.z);
          normalData.push(
            Number(item.directionX),
            Number(item.directionY),
            Number(item.directionZ)
          );
        });
        loadConstraints.forEach((load_constrains: any) => {
          if (
            load_constrains.forceInfo &&
            load_constrains.forceInfo.length !== 0
          ) {
            load_constrains.forceInfo.forEach((e: any) => {
              if (e.id === item.id) {
                console.log("normalData", normalData);
                if (e.normal) {
                  _global.Engine.model.remove(e.normal);
                  e.normal = new TArrow(normalData, pointsData);
                } else {
                  e.normal = new TArrow(normalData, pointsData);
                }
                _global.Engine.model.add(e.normal);
              }
            });
          }
        });
        // @ts-ignore
        _global.Engine.selectBoxComp.resetSelectedMeshPoint();
      });
    }
  }
  if (v.target === "DisplacementChooseSubject") {
    let node: any[] = [];
    let item = { ...parseDisplacement(selectedMaterial.value), node };
    if (
      item.dof1Value === "0.0" &&
      item.dof2Value === "0.0" &&
      item.dof3Value === "0.0" &&
      item.dof4Value === "0.0" &&
      item.dof5Value === "0.0" &&
      item.dof6Value === "0.0"
    ) {
      _global.Engine.selectBoxComp.resetSelectedMeshPoint();
    } else {
      item.node = _global.Engine.selectBoxComp.selectedPoints;
      _global.Engine.loadConstraints
        .modifyDisplacemnet(item)
        .then((res: any) => {
          const pointsData: Vector3[] = [];
          _global.Engine.selectBoxComp.selectedPoints.forEach((a) => {
            pointsData.push([a.x, a.y, a.z]);
          });
          loadConstraints.forEach((load_constrains: any) => {
            if (
              load_constrains.displacementInfo &&
              load_constrains.displacementInfo.length !== 0
            ) {
              load_constrains.displacementInfo.forEach((e: any) => {
                if (e.id === item.id) {
                  e.name = item.name;
                  if (item.node.length == 0) {
                    refreshLoadConstraintsList;
                    return;
                  }
                  if (!e.normal.dof1) {
                    e.normal.dof1 = new TCell([1, 0, 0], [1, 0, 0], pointsData);
                  }
                  if (!e.normal.dof2) {
                    e.normal.dof2 = new TCell([0, 1, 0], [0, 1, 0], pointsData);
                  }
                  if (!e.normal.dof3) {
                    e.normal.dof3 = new TCell([0, 0, 1], [0, 0, 1], pointsData);
                  }
                  if (!e.normal.dof4) {
                    e.normal.dof4 = new TCell(
                      [1, 0, 0],
                      [0.5, 0.5, 0.5],
                      e.normal.dof1.dofNext
                    );
                  }
                  if (!e.normal.dof5) {
                    e.normal.dof5 = new TCell(
                      [0, 1, 0],
                      [0.5, 0.5, 0.5],
                      e.normal.dof2.dofNext
                    );
                  }
                  if (!e.normal.dof6) {
                    e.normal.dof6 = new TCell(
                      [0, 0, 1],
                      [0.5, 0.5, 0.5],
                      e.normal.dof3.dofNext
                    );
                  }
                  if (item.dof1) {
                    _global.Engine.model.add(e.normal.dof1);
                  } else {
                    _global.Engine.model.remove(e.normal?.dof1);
                  }
                  if (item.dof2) {
                    _global.Engine.model.add(e.normal.dof2);
                  } else {
                    _global.Engine.model.remove(e.normal?.dof2);
                  }
                  if (item.dof3) {
                    _global.Engine.model.add(e.normal.dof3);
                  } else {
                    _global.Engine.model.remove(e.normal?.dof3);
                  }
                  if (item.dof4) {
                    _global.Engine.model.add(e.normal.dof4);
                  } else {
                    _global.Engine.model.remove(e.normal?.dof4);
                  }
                  if (item.dof5) {
                    _global.Engine.model.add(e.normal.dof5);
                  } else {
                    _global.Engine.model.remove(e.normal?.dof5);
                  }
                  if (item.dof6) {
                    _global.Engine.model.add(e.normal.dof6);
                  } else {
                    _global.Engine.model.remove(e.normal?.dof6);
                  }
                }
              });
            }
          });
          _global.Engine.selectBoxComp.resetSelectedMeshPoint();
        });
    }
  }
  //存储节点集合
  if (
    v.target === "nodeSet" ||
    v.target === "elementSet" ||
    v.target === "componentSet" ||
    v.target === "setSet"
  ) {
    if (v.target === "nodeSet") {
      const values = selectedMaterial.value;
      const nodes = _global.Engine.selectBoxComp.selectedPoints.map((value) => {
        return {
          nodeId: value.nodeId,
          partId: value.partId,
        };
      });
      const nodes_len = nodes.length;
      _global.Engine.set.addSet(values, nodes).then((res: string) => {
        // console.log("集合", res);
        sets.forEach((set_item) => {
          if (set_item.id == values.id) {
            set_item.value.nodeSet = nodes_len + " (nodes)";
            selectedMaterial.value = set_item.value;
            refreshItemEditor();
          }
        });
      });
      _global.Engine.set.plotNodeSet();
      _global.Engine.selectBoxComp.resetSelectedMeshPoint();
    }
    if (v.target === "elementSet") {
      let elements = _global.Engine.set.plotElementSet();
      const values = selectedMaterial.value;
      const elements_len = elements.length;
      _global.Engine.set.addSet(values, elements).then((res: string) => {
        sets.forEach((set_item) => {
          if (set_item.id == values.id) {
            set_item.value.elementSet = elements_len + " (elements)";
            selectedMaterial.value = set_item.value;
            refreshItemEditor();
          }
        });
      });
      _global.Engine.set.plotElementSet();
    }
  }

  if (v.target === "fieldFile") {
    const values = selectedMaterial.value;
    const input = document.createElement("input");
    input.type = "file";
    input.accept = ".csv"; // 设置可接受的文件类型
    input.onchange = async (e: Event) => {
      const file = (e.target as HTMLInputElement).files?.[0];
      if (!file) return;
      console.log("file", (e.target as HTMLInputElement).files);
      try {
        const fileContent = await readFileAsArrayBuffer(file);
        const result = await _global.Engine.field.load2minio(
          file.name,
          fileContent
        );
        // 后端执行选择文件接口
        fields.forEach((field_item) => {
          if (field_item.id == values.id) {
            field_item.value.fieldFile = file.name;
            selectedMaterial.value = field_item.value;
          }
          if (field_item.value.realize.fieldNodes !== "undefined (nodes)") {
            field_item.value.realize.fieldNodes = "0 (nodes)";
          }
          console.log("field_item", field_item);
          refreshItemEditor();
        });
        Message.success("场文件上传成功");
        // 刷新场列表
        refreshFieldList();
      } catch (error) {
        console.error("场文件上传失败:", error);
        Message.error("场文件上传失败");
      }
    };
    input.click();
  }
  if (v.target === "realize-fieldNodes") {
    const values = selectedMaterial.value;
    const nodes = _global.Engine.selectBoxComp.selectedPoints.map((value) => {
      return {
        nodeId: value.nodeId,
        partId: value.partId,
      };
    });
    let hasFieldFile = true;
    let fileName = "";
    fields.forEach((set_item) => {
      if (set_item.id == values.id) {
        if (set_item.value.fieldFile == "选择文件") {
          alert("请先选择场文件");
          hasFieldFile = false;
          return;
        } else {
          fileName = set_item.value.fieldFile;
        }
      }
    });
    if (!hasFieldFile) return;
    // fieldParams={name,objectId,File,nodeInfo }
    const fieldParams = {
      name: values.name,
      id: values.id,
      File: fileName,
      nodeInfo: nodes,
    };
    _global.Engine.field.addFieldnodes(fieldParams, values).then((res: any) => {
      fields.forEach((field_item) => {
        if (field_item.id == values.id) {
          field_item.value = parseField(res);
          if (res["columnSize"] > 0) {
            const columns = res["columnSize"];
            field_item.columnSize = columns;
            fieldEditorProps.fieldColumn.options = Array.from(
              { length: columns },
              (_, index) => ({
                label: `column_${index + 1}`,
                value: index,
              })
            );
          }
          field_item.value.realize.fieldNodes = res["nodes"] + " (nodes)";
          field_item.value.fieldFile = fileName;
          field_item.nodes = nodes;
          selectedMaterial.value = field_item.value;
          refreshItemEditor();
        }
      });
      _global.Engine.selectBoxComp.resetSelectedMeshPoint();
    });
  }
  if (v.target === "realize-fieldShow") {
    const values = selectedMaterial.value;
    let nodes = [];
    fields.forEach((set_item) => {
      if (set_item.id == values.id) {
        nodes = set_item.nodes;
        const file = set_item.value.fieldFile;
        if (file == "选择文件") {
          alert("请先选择场文件");
          return;
        }
        if (nodes == undefined) {
          alert("请先选择节点");
          return;
        }
        _global.Engine.field.showField();
      }
    });
  }
  if (v.target === "realize-fieldClear") {
    const values = selectedMaterial.value;
    let nodes = [];
    fields.forEach((set_item) => {
      if (set_item.id == values.id) {
        nodes = set_item.nodes;
        if (nodes == undefined) {
          return;
        }
        _global.Engine.field.clearField();
      }
    });
  }
}
function readFileAsArrayBuffer(file: File): Promise<ArrayBuffer> {
  return new Promise((resolve, reject) => {
    const reader = new FileReader();
    reader.onload = () => resolve(reader.result as ArrayBuffer);
    reader.onerror = () => reject(reader.error);
    reader.readAsArrayBuffer(file);
  });
}
// let noteTcell: NoteTcell = { x: undefined, y: undefined, z: undefined };
//计算xyz点坐标
function countCoordinate(id: number, coordinate_item: any) {
  const originalNode = coordinate_item.originalNode;
  const zNode = coordinate_item.zNode;
  const xzPlanePoint = coordinate_item.xzPlanePoint;
  const odata: number[] = [];
  const xdata: number[] = [];
  const ydata: number[] = [];
  const zdata: number[] = [];
  // 计算原点坐标
  if (originalNode) {
    odata.push(
      Number(originalNode.x),
      Number(originalNode.y),
      Number(originalNode.z)
    );
  } else {
    alert("请先选择原点");
  }
  if (zNode && originalNode) {
    const z = subtract(zNode, originalNode);
    const zAxis = normalize(z);
    zdata.push(
      Number(z.x.toFixed(6)),
      Number(z.y.toFixed(6)),
      Number(z.z.toFixed(6))
    );
    let zPoint = setOffset(originalNode, zAxis);
    if (coordinate_item.zAxis) {
      _global.Engine.model.remove(coordinate_item.zAxis);
      coordinate_item.zAxis = new TArrow(zdata, zPoint);
      coordinate_item.zAxis.setColor([[0.0, 0.0, 0.0, 1.0]]);
    } else {
      coordinate_item.zAxis = new TArrow(zdata, zPoint);
      coordinate_item.zAxis.setColor([[0.0, 0.0, 0.0, 1.0]]);
    }
    _global.Engine.model.add(coordinate_item.zAxis);
    zPoint.length = 0;
    zdata.length = 0;
  }

  //总体计算
  if (zNode && originalNode && xzPlanePoint) {
    //计算z轴
    const z = subtract(zNode, originalNode);
    const zAxis = normalize(z);
    zdata.push(
      Number(zAxis.x.toFixed(6)),
      Number(zAxis.y.toFixed(6)),
      Number(zAxis.z.toFixed(6))
    );
    let zPoint = setOffset(originalNode, zAxis);
    if (coordinate_item.zAxis) {
      _global.Engine.model.remove(coordinate_item.zAxis);
      coordinate_item.zAxis = new TArrow(zdata, zPoint);
      coordinate_item.zAxis.setColor([[0.0, 0.0, 0.0, 1.0]]);
      _global.Engine.model.add(coordinate_item.zAxis);
    } else {
      coordinate_item.zAxis = new TArrow(zdata, zPoint);
      coordinate_item.zAxis.setColor([[0.0, 0.0, 0.0, 1.0]]);
      _global.Engine.model.add(coordinate_item.zAxis);
    }
    zPoint.length = 0;
    zdata.length = 0;
    //计算x轴
    const x = subtract(xzPlanePoint, originalNode);
    const getAngle = {
      x: dotProduct(x, zAxis) * zAxis.x,
      y: dotProduct(x, zAxis) * zAxis.y,
      z: dotProduct(x, zAxis) * zAxis.z,
    };
    const xAxis = normalize(subtract(x, getAngle));
    if (dotProduct(x, xAxis) < 0) {
      xAxis.x = -xAxis.x;
      xAxis.y = -xAxis.y;
      xAxis.z = -xAxis.z;
    }
    xdata.push(
      Number(xAxis.x.toFixed(6)),
      Number(xAxis.y.toFixed(6)),
      Number(xAxis.z.toFixed(6))
    );
    let xPoint = setOffset(originalNode, xAxis);
    if (coordinate_item.xAxis) {
      _global.Engine.model.remove(coordinate_item.xAxis);
      coordinate_item.xAxis = new TArrow(xdata, xPoint);
      coordinate_item.xAxis.setColor([[0.0, 1.0, 0.0, 0.0]]);
    } else {
      coordinate_item.xAxis = new TArrow(xdata, xPoint);
      coordinate_item.xAxis.setColor([[0.0, 1.0, 0.0, 0.0]]);
    }
    _global.Engine.model.add(coordinate_item.xAxis);
    xPoint.length = 0;
    xdata.length = 0;
    //计算y轴
    const yAxis = crossProduct(zAxis, xAxis);
    ydata.push(Number(yAxis.x), Number(yAxis.y), Number(yAxis.z));
    let yPoint = setOffset(originalNode, yAxis);
    if (coordinate_item.yAxis) {
      _global.Engine.model.remove(coordinate_item.yAxis);
      coordinate_item.yAxis = new TArrow(ydata, yPoint);
      coordinate_item.yAxis.setColor([[0.0, 0.0, 1.0, 0.0]]);
    } else {
      coordinate_item.yAxis = new TArrow(ydata, yPoint);
      coordinate_item.yAxis.setColor([[0.0, 0.0, 1.0, 0.0]]);
    }
    _global.Engine.model.add(coordinate_item.yAxis);
    const id = selectedMaterial.value.id;
    yPoint.length = 0;
    ydata.length = 0;
  }
}
function coordinate_click(item: CoordinateItem) {
  // unselectAllItems();
  item.is_selected = true;
  selectedMaterial.value = item.value;
  editorProps.value = { ...loadCoordinatesEditorProps };
  propsInitial.value = { ...Load_Coordinates_TYPE_initial };
  refreshCoordinateList();
  refreshOutputblockList;
  refreshMaterialList();
  refreshItemEditor();
}

function nodeCoordinate_click(item: NodeCoordinates) {
  // unselectAllItems();
  item.is_selected = true;
  selectedMaterial.value = item.value;
  editorProps.value = { ...nodeCoordinatesEditorProps };
  propsInitial.value = { ...NODECOORDINATES_TYPE_initial };
  refreshCoordinateList();
  refreshItemEditor();
}

function materialOrientation_click(item: MaterialOrientationsItem) {
  // unselectAllItems();
  // console.log("moitem", item);
  item.is_selected = true;
  selectedMaterial.value = item.value;
  editorProps.value = { ...materialOrientationsEditorProps };
  propsInitial.value = { ...MATERIALORIENTATIONS_TYPE_initial };
  refreshCoordinateList();
  refreshItemEditor();
}

coreStore.Notify.subscribe((ev: any) => {
  if (ev.type === "SelectedMaterial") {
    console.log(ev.data);
    const a: any = {
      ...selectedMaterial.value,
      elastic_modulus: ev.data.elasticModulus + "",
      shear_modulus: ev.data.shearModulus + "",
      poisson_ratio: ev.data.poissonRatio + "",
      density: ev.data.density + "",
      tensile_stress_coefficient: ev.data.tensionStressLimit + "",
      compressive_stress_coefficient: ev.data.compressStressLimit + "",
    };
    selectedMaterial.value = a;
    refreshMaterialList();
    refreshItemEditor();
  }
});

function handleSideListClick(index: number) {
  sideList.value = sideList.value.map((v, idx) => {
    if (idx === index) {
      sideListName.value = v.name;
      return { ...v, isActive: true };
    } else {
      return { ...v, isActive: false };
    }
  });
}
</script>
<style scoped lang="less">
.side-bar-wrapper {
  height: 100%;
  box-sizing: border-box;
  // background-color: white;
  .part1 {
    display: flex;
    height: 60%;
    .part1-right {
      width: 100%;
      box-sizing: border-box;
      height: 100%;
      border-left: 1px solid #eaecef;
    }
  }
  .side-bar-item {
    height: 100%;
    display: block;
    overflow: hidden;
    .color-label {
      width: 16px;
      height: 16px;
      background-color: #20c997;
    }
    .model {
      width: 100%;
      background-color: white;
      box-sizing: border-box;
      height: 100%;
      .id-element {
        padding: 2px 5px;
        margin-right: 20px;
        box-sizing: border-box;
        width: 50px;
        display: inline-block;
        text-align: center;
      }
      .model-content {
        width: 280px;
        img {
          display: inline-block;
          margin: 1px;
          box-sizing: border-box;
        }
        .header-detail {
          .id-element {
            margin-right: 5px;
          }
          display: flex;
          flex-direction: row;
          height: 34px;
          background: #f8f9fa;
          align-items: center;
          justify-content: space-between;
          padding: 5px;
          box-sizing: border-box;
          font-family: PingFang SC;
          font-size: 14px;
          font-weight: normal;
          line-height: 22px;
          letter-spacing: 0em;

          /* content/基础base */
          /* 样式描述：--vxp-content-color-base */
          color: #495057;
          .color-box {
            display: inline-block;
            padding: 2px 6px;
            box-sizing: border-box;
            margin-right: 9px;
          }
        }
        box-sizing: border-box;
        // .geometry {
        .header {
          display: flex;
          align-items: center;
          justify-content: flex-start;
          border: 0;
          height: 48px;
          > span {
            display: inline-block;
            margin-left: 3px;
            box-sizing: border-box;
          }
        }
        // }
        .row-font {
          font-family: PingFang SC;
          font-size: 14px;
          font-weight: normal;
          line-height: 22px;
          letter-spacing: 0em;

          /* content/主要一级primary */
          /* 样式描述：--vxp-content-color-primary */
          color: #212529;
        }
        .content {
          margin-left: 40px;
          .selected {
            background-color: #edeff2;
          }
          .row {
            display: flex;
            align-items: center;
            justify-content: space-between;
            flex-direction: row;
            padding-left: 8px;
            box-sizing: border-box;
            .right {
              display: inline-flex;
              align-items: center;
              justify-content: center;
              .color-box {
                background-color: rgba(255, 255, 0, 0);
                width: 16px;
                height: 16px;
                margin-right: 21px;
              }
            }

            .left {
              display: inline-flex;
              align-items: center;
              > span {
                display: inline-block;
                margin-left: 2px;
                box-sizing: border-box;
              }
            }
          }
        }
      }
    }

    .model-editor {
      margin-top: 2%;
      background-color: white;
      overflow: hidden;
      height: 33%;
      .header-detail {
        display: flex;
        flex-direction: row;
        height: 34px;
        background: #f8f9fa;
        align-items: center;
        justify-content: space-between;
        padding: 6px;
        box-sizing: border-box;
        font-family: PingFang SC;
        font-size: 14px;
        font-weight: normal;
        line-height: 22px;
        letter-spacing: 0em;

        /* content/基础base */
        /* 样式描述：--vxp-content-color-base */
        color: #495057;
        div {
          width: 50%;
          padding: 10px;
          box-sizing: border-box;
        }
      }
      .prop-row {
        background-color: white;
        padding: 2px 5px;
        box-sizing: border-box;
        font-family: PingFang SC;
        font-size: 14px;
        font-weight: normal;
        line-height: 22px;
        letter-spacing: 0em;
        display: flex;
        flex-direction: row;
        align-items: center;
        justify-content: space-between;

        /* content/主要一级primary */
        /* 样式描述：--vxp-content-color-primary */
        color: #212529;
        > div {
          width: 50%;
          padding: 10px;
          box-sizing: border-box;
          input {
            width: 100%;
            text-align: left;
          }
        }
      }
    }
    .model-editor-header {
      height: 48px;
      width: 360px;
      background-color: #f9fbfc;
      display: flex;
      justify-content: space-between;
      align-content: center;
      padding: 0 18px;
      box-sizing: border-box;
      border-bottom: 1px solid #eaecef;
      font-size: 14px;
      font-weight: 600;
      line-height: 22px;
      letter-spacing: 0;
      /* content/主要一级primary */
      /* 样式描述：--vxp-content-color-primary */
      color: #212529;
      .header-left {
        display: flex;
        align-items: center;
      }
    }
    .header {
      height: 5%;
      width: 360px;
      background-color: #f9fbfc;
      display: flex;
      justify-content: space-between;
      align-content: center;
      padding: 0 18px;
      box-sizing: border-box;
      border-bottom: 1px solid #eaecef;
      font-size: 14px;
      font-weight: 600;
      line-height: 22px;
      letter-spacing: 0;
      /* content/主要一级primary */
      /* 样式描述：--vxp-content-color-primary */
      color: #212529;
      .header-left {
        display: flex;
        align-items: center;
      }
    }
    .add-icon {
      width: 16px;
      cursor: pointer;
    }
  }

  .geo-label {
    width: 100%;
    display: flex;
    align-items: center;
    justify-content: space-between;
    box-sizing: border-box;
    padding-right: 10px;
    .part-name {
      width: 100px;
      white-space: nowrap;
      overflow: hidden;
      text-overflow: ellipsis;
    }
  }
}

.text_overflow_single {
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}
</style>
